home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_asm / asm_kit / kermit.asm < prev    next >
Assembly Source File  |  1985-08-05  |  171KB  |  5,471 lines

  1.      .XLIST
  2. ;******************** Version 1.20  *********************************
  3. ; [20] (a) When in terminal emulation, if host sends an ESC-Z to
  4. ;      identify the terminal type being used, respond with "ESC / K".
  5. ;      (b) Allow ^X/^Z to interrupt sending a file or file group,
  6. ;      respectively.  (c) Ditto to interrupt receiving a file or file 
  7. ;      group.  (d) If get an error when receiving a file, clean up
  8. ;      and send an error packet.  Allow user to specify whether to
  9. ;      keep what made it over or to discard it.  (e) Before sending a
  10. ;      packet, clear the input buffer.  (f) Use one general routine
  11. ;      to send all error packets.  (g) Add U. of Arizona changes so
  12. ;      Kermit once again compiles on the Z100 (Joellen Windsor).  Move
  13. ;      IBM specific statements inside IBM conditional assembly blocks.
  14. ;      Daphne, 11/28/83
  15. ;******************** Version 1.19A *********************************
  16. ; [19] (a) Change NOUT to print numbers in decimal instead of hex.  
  17. ;      Routine is based on the one used in Generic Kermit.  Make a 
  18. ;      cosmetic change where print filenames & remove extraneous screen 
  19. ;      output.  Add "nop" in NAK because the jump to ABORT is only 
  20. ;      2 bytes.  Change ONTAB so the valid values are in alphabetical
  21. ;      order.  Also, keep only one copy of the code that sets the baud
  22. ;      rate and prints it's value.  (b) Allow users to choose between 
  23. ;      COM1 (default) and COM2.  Also, remind the user about which
  24. ;      communications port they are using and at what baud rate when
  25. ;      connecting to another system.  (c) Add SET BACKARROW so can 
  26. ;      set backarrow to backspace or delete. (William Dair)  Also,
  27. ;      set default to ON for renaming files due to filename conflicts. 
  28. ;      (d) When connecting to host, only bump up cursor if on line 25.
  29. ;      (e) Clean up parsing error messages.  Change VT52 emulation
  30. ;      messages to Heath-19.
  31. ;      Daphne, 10/21/83
  32. ;******************** Version 1.18 ********************************** 
  33. ; [18] A NAK for the next packet is not the same as an ACK for the
  34. ;      current packet if we're in Send-Init.  Also, account for
  35. ;      wraparound when comparing packet numbers that are off by one.
  36. ;      Daphne, 7/13/83
  37. ;******************** Version 1.3A ********************************** 
  38. ; [17] (a) Make command to SET BELL ON/OFF when transfer is complete.
  39. ;          Changed variable name to be consistent with other flags. 
  40. ;      (b) Make it more like a Heath/Zenith H19 (I/D L/C,inverse,24x80).
  41. ;      (c) Fix Telflg to be in CS so Telnet works.
  42. ;      Dave King (CMU), 7/1/83
  43. ;******************** Version 1.3 ********************************** 
  44. ; [16] Make adjustments to XT changes so that things that used to work
  45. ;      still do: pass along characters with the eighth bit on, and in
  46. ;      OUTCHR, don't overwrite character after setting the appropriate 
  47. ;      parity.
  48. ;      Daphne, 6/17/83
  49. ; [15] Add tabs stop and clear screen support.  Don't give checksum 
  50. ;      warnings.  Give keyboard input higher scheduling priority than 
  51. ;      port input.  This allows users to ^S, ^O, ^C, etc. the output 
  52. ;      when the port is full of characters.  Add a CMU conditional
  53. ;      to swap control-backspace (delete) with backspace since TOPS-20
  54. ;      and VMS are more delete than backspace oriented.
  55. ;      Glenn Marcy, 6/8/83
  56. ; [14] Add CMU changes that allow Kermit to work on the XT.  Plus add
  57. ;      a statement omitted previously when comparing packet numbers.   
  58. ;      Daphne, 5/26/83  (changes by Dave King, CMU)
  59. ;******************** Version 1.2 ********************************** 
  60. ; [13] When closing received file, handle case where number of bytes is
  61. ;      divisible by 128.
  62. ;      Daphne, 5/2/83
  63. ;******************** Version 1.1 ********************************** 
  64. ; [12] If "SET IBM", set local echo, XON/XOFF, and default (mark) parity.
  65. ;      Daphne, 4/15/83
  66. ; [11] In RPACK, don't push packet type, but store in temp variable.
  67. ;      If push and get an error, you pick up packet type as return addr.
  68. ;      Daphne, 4/15/83 
  69. ; [10] Add Set Parity Command.
  70. ;      Daphne, 4/12/83
  71. ; [9]  Allow single-character wildcard in filenames, use "=".
  72. ;      Daphne, 4/4/83
  73. ; [8]  Add Kermit server support.
  74. ;      Daphne, 3/17/83
  75. ; [7]  Allow wildcards in filename.
  76. ;      Daphne, 3/15/83
  77. ; [6]  Make format of "Set Escape" look like the other commands.
  78. ;      Daphne, 3/14/83
  79. ; [5]  Add Set "End-of-Line" (to the char used to terminate packets I send).
  80. ;      Daphne, 3/7/83
  81. ; [4]  Ring bell when done (when succeed and when fail).
  82. ;      Daphne, 2/10/83
  83. ; [3]  Match keyword if "?" is the terminator.
  84. ;      Daphne, 2/9/83
  85. ; [2]  Change "Inpkt" so ignores bare CR from any system. 
  86. ;      Daphne, 2/9/83
  87. ; [1]  Add "cmer04" - print error message if run off list of commands allowed.
  88. ;      Daphne, 2/9/83     
  89.  
  90. ;******************** Version 1.0 ********************************** 
  91. ; KERMIT - KL10 Error-free Reciprocal Micro Interconnect over TTY-lines
  92. ;       Program Version 1.20, Kermit Protocol Version 2
  93. ;    November 4, 1983
  94. ;       Based on the KERMIT Protocol.
  95. ;       Copyright (C) 1982,1983 Trustees of Columbia University
  96. ;
  97. ;       Daphne Tzoar
  98. ;       Columbia University Computer Center
  99. ;       612 W. 115th St.
  100. ;       New York City, NY  10025
  101. ;  Special thanks to Frank da Cruz, Bill Catchings, Steve Jensen,
  102. ;  Vace Kundakci, and Bernie Eiben for their help and contributions.
  103.  
  104.  
  105. ;  This file is the global data area for all the Kermit modules.
  106.  
  107.  
  108. CMU    EQU    0        ; CMU conditional assembly. [15]
  109. IBMPC   EQU     1               ; For IBM PC conditional assembly.
  110. Z100    EQU    0        ; For Heath/Zenith Z-100. 
  111. STEVE   EQU     0               ; For Steve's homebrew assembly.
  112.  
  113. BELL    EQU     07Q
  114. TAB     EQU     11Q
  115. LF      EQU     12Q
  116. FF      EQU     14Q
  117. CR      EQU     15Q
  118. XON     EQU     21Q
  119. XOFF    EQU     23Q
  120. ESC     EQU     33Q
  121. DEL     EQU     177Q
  122. BS    EQU    08H
  123.  
  124. DOS     EQU     21H
  125.  
  126. CONIN   EQU     01H
  127. CONOUT  EQU     02H
  128. RDRIN   EQU     03H
  129. PUNOUT  EQU     04H
  130. LSTOUT  EQU     05H
  131. DCONIO  EQU     06H
  132. GTIOB   EQU     07H
  133. PRSTR   EQU     09H
  134. CONSTAT EQU     0BH
  135. OPENF   EQU     0FH
  136. CLOSF   EQU     10H
  137. SFIRST  EQU     11H
  138. SNEXT   EQU     12H
  139. DELF    EQU     13H
  140. READF   EQU     14H             ; Read from the file.
  141. WRITEF  EQU     15H
  142. MAKEF   EQU     16H
  143. SETDMA    EQU    1AH
  144. CFLSZ   EQU     23H
  145.  
  146. MAXPKT  EQU     '~'-' '+2Q      ; Maximum size of a packet.
  147. MAXTRY  EQU     05Q             ; Default number of retries on a packet.
  148. IMXTRY  EQU     20Q             ; Default number of retries send initiate.
  149. DRPSIZ  EQU     5EH             ; Default receive packet size.
  150. DSPSIZ  EQU     20H             ; Default send packet size.
  151. DSTIME  EQU     08H             ; Default send time out interval.
  152. DRTIME  EQU     05H             ; Default receive time out interval.
  153. DSPAD   EQU     00H             ; Default send padding.
  154. DRPAD   EQU     00H             ; Default receive padding.
  155. DSPADC  EQU     00H             ; Default send padding char.
  156. DRPADC  EQU     00H             ; Default receive padding char.
  157. DSEOL   EQU     CR              ; Default send EOL char.
  158. DREOL   EQU     CR              ; Default receive EOL char.
  159. DSQUOT  EQU     '#'             ; Default send quote char.
  160. DRQUOT  EQU     '#'             ; Default receive quote char.
  161.  
  162. PAREVN    EQU    00H        ; Even parity.            [10 start]
  163. PARMRK    EQU    01H        ; Mark parity.
  164. PARNON    EQU    02H        ; No parity.    
  165. PARODD    EQU    03H        ; Odd parity.
  166. PARSPC    EQU    04H        ; Space parity.
  167. DEFPAR    EQU    PARNON        ; Default parity (none.) 
  168. IBMPAR  EQU    PARMRK        ; IBM's parity (mark.)        [10 end]
  169.  
  170. SOH     EQU     01H             ; Start of header char.
  171. BUFSIZ  EQU     80H             ; Size of DMA.
  172. DIASW   EQU     01H             ; Default is diagnostics on.
  173.  
  174. CMKEY   EQU     01H             ; Parse a keyword.
  175. CMIFI   EQU     02H             ; Parse an input file spec (can be wild).
  176. CMOFI   EQU     03H             ; Parse an output file spec.
  177. CMCFM   EQU     04H             ; Parse a confirm.
  178. CMTXT    EQU    05H        ; Parse arbitrary text up to CR.   [8]
  179.  
  180. IF ibmpc
  181. BIOS    EQU     10H
  182. COMM    EQU    14H
  183. KEYB    EQU    16H
  184. DEFESC  EQU     ']'-100Q        ; The default escape character.
  185. MDMDAT1    EQU    03F8H        ; Address of modem port (data). [19b]
  186. MDMSTS1    EQU    03FDH        ; Address of modem port    status. [19b]
  187. MDMCOM1    EQU    03FBH        ; Address of modem port command. [19b]
  188. MDMDAT2    EQU    02F8H        ; Port 2 address. [19b]
  189. MDMSTS2    EQU    02FDH        ; Port 2 status. [19b]
  190. MDMCOM2    EQU    02FBH        ; Port 2 command. [19b]
  191. MDMINP    EQU    1        ; Input ready bit.
  192. BRKBIT    EQU    040H        ; Send-break bit. [20g]
  193. MDMINTV    EQU    0030H        ; Address of modem port interrupt vector.
  194. MDINTV2 EQU    002CH        ; Address for port 2. [19b] 
  195. MDMINTO    EQU    0EFH        ; Mask to enable interrupt for modem port.
  196. MDINTO2 EQU    0F7H        ; Enable interrupt level 3. [19b]
  197. MDMINTC    EQU    010H        ; Bit to set to disable interrupts for modem.
  198. MDINTC2 EQU    008H        ; Disable IRQ3. [19b]
  199. INTCONT    EQU    0021H        ; Address of 8259 interrupt controller ICW2-3.
  200. INTCON1    EQU    0020H        ; Address of 8259 ICW1.
  201. EOICOM    EQU    0064H        ; End of interrupt.
  202. EOICOM2    EQU    0063H        ; End of interrupt for COM2. [19b]
  203. TIMER    EQU    40H        ; Use to issue short beep.
  204. PORT_B    EQU    61H        ; Port B address.
  205.  
  206. B0300    EQU    180H        ; Variables for 300 baud, 1200, etc.
  207. B1200    EQU    60H
  208. B1800    EQU    40H
  209. B2400    EQU    30H
  210. B4800    EQU    18H
  211. B9600    EQU    0CH
  212. ENDIF
  213.  
  214. IF Z100
  215. MDMCOM    EQU    0EFH        ; Asynch port command register. [20g]
  216. BRKBIT    EQU    048H        ; Send-break bits. [20g]
  217. DEFESC  EQU     '\'-100Q        ; The default escape character.
  218.  
  219. ; BIOS entry points
  220.  
  221. BIOS_SEG SEGMENT AT 40H        ; Define segment where BIOS really is
  222.  
  223.     ORG    6*3
  224. BIOS_AUXOUT LABEL FAR        ; AUX output routine
  225.  
  226.     ORG    26*3
  227. BIOS_AUXFUNC LABEL FAR        ; AUX: function
  228.  
  229. BIOS_SEG ENDS            ; End of BIOS segment defs
  230.  
  231. ; Function codes for BIOS_AUXFUNC
  232. CHR_READ    EQU    1    ; Read character
  233. CHR_STATUS    EQU    2    ; Get status
  234.   CHR_SFGS    EQU    0    ; Get status subfunction
  235.   CHR_SFGC    EQU    1    ; Get config subfunction
  236. CHR_CONTROL    EQU    3    ; Control function
  237.  CHR_CFSU    EQU    0    ; Set new configuration parameters
  238.  
  239. B00455    EQU    0        ; 45.5 baud
  240. B0050    EQU    1        ; 50 baud
  241. B0075    EQU    2        ; 75 baud
  242. B0110    EQU    3        ; 110 baud
  243. B01345    EQU    4        ; 134.5 baud
  244. B0150    EQU    5        ; 150 baud
  245. B0300    EQU    6        ; 300 baud
  246. B0600    EQU    7        ; 600 baud
  247. B1200    EQU    8        ; 1200 baud
  248. B1800    EQU    9        ; 1800 baud
  249. B2000    EQU    10        ; 2000 baud
  250. B2400    EQU    11        ; 2400 baud
  251. B4800    EQU    12        ; 4800 baud
  252. B9600    EQU    13        ; 9600 baud
  253. B19200    EQU    14        ; 19200 baud
  254. B38400    EQU    15        ; 38400 baud 
  255. ENDIF
  256.  
  257. STACK   SEGMENT PARA STACK 'STACK'
  258.         DW      100 DUP(0)      ; Initialize stack to all zeros.
  259. STK    EQU    THIS WORD
  260. STACK   ENDS
  261.  
  262. DATAS   SEGMENT PARA PUBLIC 'DATAS'
  263.  
  264.         ; Pure storage.
  265.  
  266. versio  db      'CUCCA'
  267. IF ibmpc
  268.     db    ' IBM-PC' 
  269. ENDIF
  270. IF Z100
  271.     db    '/Stevens Heath/Zenith Z-100'
  272. ENDIF
  273.     db    ' Kermit-86 - ver 1.20',cr,lf,'$'       ;[19a]
  274. kerm    db      'Kermit-86>$'
  275. spmes   db    'Spack:  $'
  276. rpmes     db    'Rpack:  $'
  277. hibit    db    'Warning - Non Ascii char$'
  278. tmp    db    ?
  279. foo    db    '$'
  280. crlf    db      cr,lf,'$'
  281. ender    db    bell,bell,'$'             ;  [4]
  282. tmsg1    db    cr,lf,'[Connecting to host, type $' 
  283. tmsg3    db    ' C to return to PC$'     ; [17b, 19b]
  284. tmsg2    db    cr,lf,'[Back at micro]',cr,lf,'$'
  285. tmsg4    db    ', connecting over port COM$'  ; [19b]
  286. ermes1  db      cr,lf,'?Unregonized command$'
  287. ermes2  db      cr,lf,'?Illegal character$'
  288. ermes3  db      cr,lf,'?Not confirmed$'
  289. ermes4  db      'Unable to rename file$'
  290. ermes7  db      '?Unable to receive initiate$'
  291. ermes8  db      '?Unable to receive file name$'
  292. ermes9  db      '?Unable to receive end of file$'
  293. erms10  db      '?Unable to receive data$'
  294. erms11  db      '?Disk full$'
  295. erms14  db      '?Unable to receive an acknowledgement from the host$'
  296. erms15  db      '?Unable to find file$'
  297. erms17  db    'Record length exceeds size of buffer$'
  298. erms18    db    cr,lf,'?Unable to tell host that session is finished$'
  299. erms19    db    cr,lf,'?Unable to tell host to logout$'
  300. infms0  db      'Waiting .....$'
  301. infms1  db      'Receiving ...$'
  302. infms2  db      'Sending .....$'
  303. infms3  db      'Completed    $'
  304. infms4  db      'Failed       $'
  305. infms5  db      'Renaming file to $'
  306. infms6  db      'Interrupted  $'        ; [20b]
  307. infms7    db    'File interrupt: OK  $'       ; [20b] 
  308. infms8    db    'File group interrupt: OK  $'   ; [20b] 
  309.  
  310. cfrmes  db      ' Confirm with carriage return $'
  311. filhlp  db      ' Input file spec (possibly wild) $'
  312. esctl    db    'Control-$'         ; [6]
  313. spchar    db    24H,26H,23H,40H,21H,25H,27H,28H,29H,2DH
  314.     db    3CH,3EH,7BH,7DH,5FH,5CH,5EH,7EH,7CH,60H
  315. eschlp  db      cr,lf,'Enter literal value (ex: Cntrl ])  $'
  316. tophlp  db    cr,lf,'BYE to host (LOGOUT) and exit to DOS'
  317.     db      cr,lf,'CONNECT to host on selected port'
  318.         db      cr,lf,'EXIT to DOS'
  319.     db    cr,lf,'FINISH running Kermit on the host'
  320.         db      cr,lf,'HELP by giving this message'
  321.     db    cr,lf,'LOGOUT the host'
  322.         db      cr,lf,'RECEIVE file from host'
  323.         db      cr,lf,'SEND file to host'
  324.         db      cr,lf,'SET a parameter'
  325. ;        db      cr,lf,'SHOW the parameters'
  326.         db      cr,lf,'STATUS of Kermit$'
  327. sethlp    db    cr,lf,'BACKARROW to'        ; [19c]
  328.     db      cr,lf,'BAUD rate'    
  329.     db    cr,lf,'BELL'    ; [17a]
  330.     db    cr,lf,'DEBUG'
  331.     db    cr,lf,'END-OF-LINE character'
  332.     db      cr,lf,'ESCAPE character change'
  333.         db      cr,lf,'FILE-WARNING'
  334. IF ibmpc
  335.         db      cr,lf,'HEATH-19'        ; [19e]
  336. ENDIF
  337.     db    cr,lf,'IBM'
  338.     db    cr,lf,'INCOMPLETE file'        ; [20d]
  339.         db      cr,lf,'LOCAL-ECHO echoing (half-duplex)'
  340.     db    cr,lf,'PARITY type'                 ; [10]
  341. IF ibmpc
  342.     db    cr,lf,'PORT for communication$'     ; [19b]
  343. ;        db      cr,lf,'VT52-EMULATION$'           ; [19e]
  344. ENDIF
  345. IF Z100
  346.     db    '$'
  347. ENDIF    
  348. stshlp  db      cr,lf,'PAD-CHAR'
  349.         db      cr,lf,'PADDING$'
  350. onhlp   db      cr,lf,'OFF      ON$'
  351. yeshlp  db      cr,lf,'NO       YES$'
  352. abfhlp    db    cr,lf,'DISCARD      KEEP$'        ; [20d]
  353. comphlp    db    cr,lf,'1 (COM1)   2 (COM2)$'        ; [19b]
  354. parhlp    db    cr,lf,'None   Mark   Odd   Even   Space$'   ; [10]
  355. IF ibmpc
  356. bdhlp    db    cr,lf,'300   1200   1800   2400   4800   9600$'
  357. ENDIF
  358. IF Z100
  359. bdhlp    db    cr,lf,'45.5    50    75    110    134.5    150    300'
  360.     db    '    600    1200    1800'
  361.     db    cr,lf,'    2000    2400    4800    9600    19200    38400'
  362. ENDIF
  363. BShlp    db    cr,lf,'BACKSPACE      DELETE$'        ; [19c]
  364. eolhlp    db    cr,lf,'Decimal digit between 0 and 31$'   ; [5]
  365. eolerr    db    cr,lf,'Illegal end-of-line character$'  ; [5]
  366. inthlp  db      cr,lf,'?  This message'
  367.         db      cr,lf,'C  Close the connection'
  368.         db      cr,lf,'S  Status of the connection'
  369.     db    cr,lf,'B  Send a break'            ; [20g]
  370.         db      cr,lf,'Typing the escape character will send it to the host'
  371.         db      cr,lf,cr,lf,'Command>$'
  372. locst   db      cr,lf,'Local echo on$'
  373. remst   db      cr,lf,'Local echo off$'
  374. belon    db    cr,lf,'Ring bell at end of transfer$'     ; [17a - DT]
  375. beloff    db    cr,lf,'No bell at end of transfer$'       ; [17a - DT]
  376. IF ibmpc
  377. vtemst  db      cr,lf,'HEATH-19 emulation on$'        ; [19e]
  378. novtst  db      cr,lf,'HEATH-19 emulation off$'        ; [19e]
  379. cm1st    db    cr,lf,'Using communications port 1$'    ; [19b]
  380. cm2st    db    cr,lf,'Using communications port 2$'    ; [19b]
  381. ENDIF
  382. ibmst   db      cr,lf,'IBM on$'
  383. noibm   db      cr,lf,'IBM off$'
  384. pnonst    db    cr,lf,'No parity$'               ; [10]
  385. poddst    db    cr,lf,'Odd parity$'                ; [10]
  386. pevnst    db    cr,lf,'Even parity$'               ; [10]
  387. pmrkst    db    cr,lf,'Mark parity$'               ; [10]
  388. pspcst    db    cr,lf,'Space parity$'              ; [10]
  389. IF Z100 
  390. b04st    db    cr,lf,'Baud rate is 45.5$'
  391. b05st    db    cr,lf,'Baud rate is 50$'
  392. b07st    db    cr,lf,'Baud rate is 75$'
  393. b11st    db    cr,lf,'Baud rate is 110$'
  394. b13st    db    cr,lf,'Baud rate is 134.5$'
  395. b15st    db    cr,lf,'Baud rate is 150$'
  396. b06st    db    cr,lf,'Baud rate is 600$'
  397. b20st    db    cr,lf,'Baud rate is 2000$'
  398. b19st    db    cr,lf,'Baud rate is 19200$'
  399. b38st    db    cr,lf,'Baud rate is 38400$'
  400. ENDIF
  401. b03st    db    cr,lf,'Baud rate is 300$'
  402. b12st    db    cr,lf,'Baud rate is 1200$'
  403. b18st    db    cr,lf,'Baud rate is 1800$'
  404. b24st    db    cr,lf,'Baud rate is 2400$'
  405. b48st    db    cr,lf,'Baud rate is 4800$'
  406. b96st    db    cr,lf,'Baud rate is 9600$'
  407. debon    db    cr,lf,'Debug mode on$'
  408. deboff    db    cr,lf,'Debug mode off$'    
  409. flwon    db    cr,lf,'File Warning on$'
  410. flwoff    db    cr,lf,'File Warning off$'
  411. bkbs    db      cr,lf,'Backarrow sends a backspace $'   ; [19c] 
  412. bkdel   db      cr,lf,'Backarrow sends a delete $'      ; [19c] 
  413. abfdst    db    cr,lf,'Discard incoming file if incomplete $'  ;[20d]
  414. abfkst    db    cr,lf,'Keep incoming file if incomplete $'   ;[20d]
  415. eolst    db    cr,lf,'End-of-line character is ^$'     ; [5]
  416. escmes  db      cr,lf,'Escape character is  $'          ; [6]
  417.  
  418.  
  419. outlin  db      cr,lf,'                CUCCA'
  420. IF ibmpc
  421.     db    ' IBM-PC'
  422. ENDIF
  423. IF Z100
  424.     db    '/Stevens Heath/Zenith Z-100'
  425. ENDIF
  426.     db    ' Kermit-86 V1.20',cr,lf
  427.         db      cr,lf,'Number of packets:   '    ; [19a]
  428.         db      cr,lf,'Number of retries:   '    ; [19a]
  429.         db      cr,lf,'File name $'
  430. delstr  db      10O,' ',10O,10O,'$'     ; Delete string.
  431. clrspc  db      ' ',10O,'$'             ; Clear space.
  432. escspc    db    10O,' ',10O,'$'        ; Clear escape.
  433. IF ibmpc
  434. clrlin  db      cr,'$'            ; Clear line (just the cr part).
  435. ENDIF
  436. IF Z100
  437. clrlin    db    cr,esc,'K$'        ; Clear line on Z-100
  438. clreol    db    esc,'K$'        ; Clear to end of line
  439. clrscr    db    esc,'H',esc,'J$'    ; Home and clear screen
  440. homcur    db    esc,'H$'        ; Home cursor
  441. ENDIF
  442. prsp    db    ' $'            ; Print a space.
  443.  
  444. ; Cursor addressing items.
  445.  
  446. IF ibmpc
  447. scrhi    dw    0434H            ; Err when 8th bit is on.
  448. scrrpr    dw    0700H            ; Prompt when Kermit ends.
  449. screrr  dw      0600H                ; Place for error msgs. 
  450. scrfln  dw      050CH            ; Place for file name.
  451. scrnrt  dw      0415H                ; Place for number of retries.
  452. scrnp   dw      0315H                 ; Place for number of packets.
  453. scrfr    dw    0600H            ; Rename file.
  454. scrst    dw    0334H            ; Place for status.
  455. scrint    dw    0434H            ; Acknowledge interrupt. [20b]
  456. scrsp    dw    0800H            ; Place for send packet.
  457. scrrp    dw    0A00H            ; Place for receive packet.
  458.  
  459. ttab    label    word            ; Table for cursor movement.
  460. ta    dw    curup            ; Cursor up.
  461. tb    dw    curdwn            ; Cursor down.
  462. tc    dw    currt              ; Cursor right.
  463. td    dw    curlft            ; Cursor left.
  464. te    dw    curclr            ; Clear display. [15]
  465. tf    dw    curskp            ; Enter graphics mode.
  466. tg    dw    curskp            ; Exit graphics mode.
  467. th    dw    curhm            ; Cursor home.
  468. ti    dw    curup            ; Reverse line feed.
  469. tj    dw    curscr            ; Clear to end of screen.
  470. tk    dw    curln            ; Clear to end of line.
  471. tl    dw    inslin            ; Insert line.
  472. tm    dw    dellin            ; Delete line.    
  473. tn    dw    delchr            ; Delete character. [17b] 
  474. to    dw    insmox            ; Cancel Insert Character. [17b] 
  475. ENDIF
  476.  
  477. IF Z100
  478. scrhi    db    esc,'Y',23H,54H,lf,'$'    ; 8th bit on in character
  479. scrrpr    db    esc,'Y',27H,20H,'$'    ; Prompt when Kermit ends
  480. screrr    db    esc,'Y',26H,20H,'$'    ; Error messages
  481. scrfln    db    esc,'Y',25H,2CH,'$'    ; File name
  482. scrnrt    db    esc,'Y',23H,35H,lf,'$'    ; Number of retries
  483. scrnp    db    esc,'Y',23H,35H,'$'    ; Number of packets
  484. scrfr    db    esc,'Y',26H,20H,'$'    ; Rename file
  485. scrst    db    esc,'Y',23H,54H,'$'    ; Status
  486. scrint  db    esc,'Y',24H,54H,'$'    ; Acknowledge interrupt. [20b]
  487. scrsp    db    esc,'Y',28H,20H,'$'    ; send packet
  488. scrrp    db    esc,'Y',2AH,20H,'$'    ; Receive packet
  489. ENDIF
  490.  
  491.         ; COMND tables
  492.  
  493. comtab  db      0AH                 ; Ten entries.
  494.     db    03H,'BYE$'
  495.     dw    bye
  496.         db      07H,'CONNECT$'
  497.         dw      telnet
  498.         db      04H,'EXIT$'
  499.         dw      exit
  500.     db    06H,'FINISH$'
  501.     dw    finish
  502.         db      04H,'HELP$'
  503.         dw      help
  504.     db    06H,'LOGOUT$'
  505.     dw    logout
  506.         db      07H,'RECEIVE$'
  507.         dw      read
  508.         db      04H,'SEND$'
  509.         dw      send
  510.         db      03H,'SET$'
  511.         dw      setcom
  512.         db      06H,'STATUS$'
  513.         dw      status
  514.  
  515. IF ibmpc
  516. settab  db      0DH             ; Thirteen entries. [17a][19b][19c][20d]
  517. ENDIF
  518. IF Z100
  519. settab  db      0BH             ; Eleven entries.   [10][17a][19c][20d]
  520. ENDIF
  521.     db    09H,'BACKARROW$'    ; [19c]
  522.     dw    BSset             ; [19c]
  523.     db    04H,'BAUD$'
  524.     dw    baudst
  525.     db    04H,'BELL$'    ; [17a]
  526.     dw    bellst        ; [17a]
  527.     db    05H,'DEBUG$'
  528.     dw    debst
  529.     db    0BH,'END-OF-LINE$'             ;  [5]
  530.     dw    eolset                 ;  [5]
  531.         db      06H,'ESCAPE$'
  532.         dw      escape
  533.     db    0CH,'FILE-WARNING$'
  534.     dw    filwar
  535. IF ibmpc
  536.         db      0DH,'H19-EMULATION$'        ; [19e]
  537.         dw      vt52em                ; [19e]
  538. ENDIF
  539.         db      03H,'IBM$'
  540.         dw      ibmset
  541.     db    0AH,'INCOMPLETE$'       ; [20d]
  542.     dw    abfset            ; [20d]
  543.         db      0AH,'LOCAL-ECHO$'
  544.         dw      lcal
  545.     db    06H,'PARITY$'                ; [10]
  546.     dw    setpar                    ; [10]
  547. IF ibmpc
  548.     db    04H,'PORT$'            ; [19b]
  549.     dw    comset                ; [19b]
  550. ;        db      0EH,'VT52-EMULATION$'        ; [19e]
  551. ;        dw      vt52em                ; [19e]
  552. ENDIF
  553.  
  554. ontab   db      02H             ; Two entries.
  555.         db      03H,'OFF$'    ; Should be alphabetized.  [19a]
  556.         dw      00H
  557.         db      02H,'ON$'
  558.         dw      01H
  559.  
  560. ; If abort when receiving files, can keep what we have or discard. [20d]
  561.  
  562. abftab    db    02H        ; Only two options. 
  563.     db    07H,'DISCARD$'
  564.     dw    01H
  565.     db    04H,'KEEP$'
  566.     dw    00H
  567.  
  568. ; Entries for choosing communications port. [19b]
  569.  
  570. comptab    db    04H
  571.     db    01H,'1$'
  572.     dw    01H
  573.     db    01H,'2$'
  574.     dw    00H
  575.     db    04H,'COM1$'
  576.     dw    01H
  577.      db    04H,'COM2$'
  578.     dw    00H
  579.  
  580. yestab  db      02H             ; Two entries.
  581.         db      02H,'NO$'
  582.         dw      00H
  583.         db      03H,'YES$'
  584.         dw      01H
  585.  
  586. partab    db    05H        ; Five entries.            [10 start]
  587.     db    04H,'EVEN$'
  588.     dw    PAREVN
  589.     db    04H,'MARK$'
  590.     dw    PARMRK
  591.     db    04H,'NONE$'
  592.     dw    PARNON
  593.     db    03H,'ODD$'
  594.     dw    PARODD
  595.     db    05H,'SPACE$'
  596.     dw    PARSPC                        ;[10 end]
  597.  
  598. BStab    db    02H            ;Two entries [19c start]
  599.     db    09H,'BACKSPACE$'
  600.     dw    00H
  601.     db    06H,'DELETE$'
  602.     dw    01H            ;[19c]
  603.  
  604. IF ibmpc
  605. bdtab    db    06H        ; Six entries.
  606.     db    04H,'1200$'
  607.     dw    B1200
  608.     db    04H,'1800$'
  609.     dw    B1800
  610.     db    04H,'2400$'
  611.     dw    B2400
  612.     db    03H,'300$'
  613.     dw    B0300
  614.     db    04H,'4800$'
  615.     dw    B4800
  616.     db    04H,'9600$'
  617.     dw    B9600
  618. ENDIF
  619. IF Z100
  620. bdtab    db    010H        ; 16 entries
  621.     db    03H,'110$'
  622.     dw    b0110
  623.     db    04H,'1200$'
  624.     dw    b1200
  625.     db    03H,'134$'
  626.     dw    b01345
  627.     db    03H,'150$'
  628.     dw    b0150
  629.     db    04H,'1800$'
  630.     dw    b1800
  631.     db    05H,'19200$'
  632.     dw    b19200
  633.     db    04H,'2000$'
  634.     dw    b2000
  635.     db    04H,'2400$'
  636.     dw    b2400
  637.     db    03H,'300$'
  638.     dw    b0300
  639.     db    05H,'38400$'
  640.     dw    b38400
  641.     db    02H,'45$'
  642.     dw    b00455
  643.     db    04H,'4800$'
  644.     dw    b4800
  645.     db    02H,'50$'
  646.     dw    b0050
  647.     db    03H,'600$'
  648.     dw    b0600
  649.     db    02H,'75$'
  650.     dw    b0075
  651.     db    04H,'9600$'
  652.     dw    b9600
  653. ENDIF
  654.  
  655. ; COMND storage
  656.  
  657. cmer00  db      cr,lf,'?Program error   Invalid COMND call$'
  658. cmer01  db      cr,lf,'?Ambiguous$'
  659. cmer02  db      cr,lf,'?Illegal input file spec$'
  660. ;cmer03    db    cr,lf,'?Unrecognized instruction$'
  661. cmer03    db    cr,lf,'?Invalid command$'         ;  [19e]
  662. cmer04    db    cr,lf,'?Invalid command or operand$'     ;  [1]
  663. cmin00  db      ' Confirm with carriage return$'
  664. cmcrlf  db      cr,lf,'$'
  665.  
  666. cmstat  db      ?               ; What is presently being parsed.
  667. cmaflg  db      ?               ; Non-zero when an action char has been found.
  668. cmccnt  db      ?               ; Non-zero if a significant char is found.
  669. cmsflg  db      ?               ; Non-zero when the last char was a space.
  670. cmostp  dw      ?               ; Old stack pointer for reparse.
  671. cmrprs  dw      ?               ; Address to go to on reparse.
  672. cmprmp  dw      ?               ; Address of prompt.
  673. cmptab  dw      ?               ; Address of present keyword table.
  674. cmhlp   dw      ?               ; Address of present help.
  675. cmdbuf  db      80H DUP(?)      ; Buffer for command parsing.
  676. cmfcb   dw      ?               ; Pointer to FCB.
  677. cmfcb2  dw      ?               ; Pointer to position in FCB.
  678. cmcptr  dw      ?               ; Pointer for next char input.
  679. cmdptr  dw      ?               ; Pointer into the command buffer.
  680. cmsiz    dw    ?        ; Size info of user input.
  681. cmkptr  dw      ?               ; Pointer to keyword.
  682. cmsptr  dw      ?               ; Place to save a pointer.
  683. cmchr    db    ?        ; Save char when checking ambiguity.
  684.  
  685. ; Program storage.
  686.  
  687. oldstk  dw      ?               ; Storage for system stack.
  688. oldsts  dw      ?               ; System stack segment.
  689. ssp    dw    0        ; Save SP in Telnet.
  690. bufhex    dw    80H
  691. filsiz    dd    0        ; Double word for filesize (in bytes.)
  692. eoflag  db      ?               ; EOF flag; non-zero on EOF.
  693. wldflg    db    0        ; Assume no "*" in fn.         [7]
  694. ;telflg    db    0        ; Are we acting as a terminal. [16] [17c]
  695. belflg    db    1        ; Use bell  [17a -- DT]
  696. comflg    db    1        ; Use COM1 by default. [19b]
  697. cxzflg    db    0        ; ^X/^Z to interrupt file x-fer. [20b] 
  698. abfflg    db    1        ; Discard incoming file if abort. [20d]
  699. debug    db    0        ; Debugging mode (default off).
  700. hierr    db    0        ; Non-ascii char (non-zero if yes).
  701. filflg  db      ?               ; Non-zero when nothing in DMA buffer.
  702. ecoflg  db      0               ; Local echo flag (default off).
  703. parflg  db    defpar        ; Parity flag (default none.)  [10]
  704. escflg  db      0               ; Escape flag (start off).
  705.  
  706. IF ibmpc
  707. vtflg   db      1               ; VT52 emulation flag (default on).
  708. incmod    db    0        ; Insert Character mode.  [17b] [20g]
  709. curatt    dw    0007H        ; Video attributes. [17b]
  710. baud    dw    B4800        ; Use default of 4800.
  711. mddat    dw    MDMDAT1        ; Default to port 1. [19b start]
  712. mdstat    dw    MDMSTS1        ; Ditto. 
  713. mdcom    dw    MDMCOM1        ; Here too. 
  714. mden    db    MDMINTO
  715. mddis    db    MDMINTC
  716. mdmeoi    db    EOICOM
  717. mdintv    dw    MDMINTV        ; [19b end]
  718. ENDIF
  719. IF Z100
  720. auxcnf    db    4 dup(?)    ; AUX port configuration info
  721. baud    db    ?        ; Baud rate
  722. auxcnf1    db    12 dup(?)    ; Rest of configuration info
  723. mdcom    dw    MDMCOM        ; Use to send a break. [20g]
  724. ENDIF
  725.  
  726. flwflg  db      1               ; File warning flag (default on). [19c]
  727. ibmflg  db      0               ; IBM flag (default off).
  728. delflg    db    1        ; Do BS to DEL translation. [19c]
  729. extflg  db      0               ; Exit flag (default off).
  730. escchr  db      defesc          ; Storage for the escape character.
  731. incnt    dw    ?        ; Number of chars read in from port.
  732. chrcnt  dw      ?               ; Number of chars in the file buffer.
  733. filcnt  dw      ?               ; Number of chars left to fill.
  734. outpnt  dw      ?               ; Position in packet.
  735. bufpnt  dw      ?               ; Position in file buffer.
  736. fcbptr  dw      ?               ; Position in FCB.
  737. datptr  dw      ?               ; Position in packet data buffer.
  738. cbfptr  dw      ?               ; Position in character buffer.
  739. pktptr  dw      ?               ; Poistion in receive packet.
  740. siz     dw      ?               ; Size of data from gtchr.
  741. spsiz   db      dspsiz          ; Send packet size.
  742. rpsiz   db      drpsiz          ; Receive packet size.
  743. stime   db      dstime          ; Send time out.
  744. rtime   db      drtime          ; Receive time out.
  745. spad    db      dspad           ; Send padding.
  746. rpad    db      drpad           ; Receive padding.
  747. spadch  db      dspadc          ; Send padding char.
  748. rpadch  db      drpadc          ; Receive padding char.
  749. seol    db      dseol           ; Send EOL char.
  750. reol    db      dreol           ; Receive EOL char.
  751. squote  db      dsquot          ; Send quote char.
  752. rquote  db      drquot          ; Receive quote char.
  753. pktnum  dw      ?               ; Packet number.
  754. numpkt  dw      ?               ; Total number of packets sent.
  755. numrtr  dw      ?               ; Total number of retries.
  756. numtry  db      ?               ; Number of tries on this packet.
  757. oldtry  db      ?               ; Number of tries on previous packet.
  758. state   db      ?               ; Present state of the automaton.
  759. savsci    dw    ?        ; Save for serial port interrupt vector. [14]
  760. savscs    dw    ?        ; Ditto.  [14]  
  761. packet  db      ?,?,?,?         ; Packet (data is part of it).
  762. data    db      5AH DUP(?)      ; Data and checksum field of packet.
  763. recpkt  db      60H DUP(?)      ; Receive packet storage (use the following).
  764. filbuf  db      60H DUP(?)      ; Character buffer.
  765. fcb    db    25H DUP(?)    ; Use as our FCB.
  766. cpfcb    db    25H DUP(?)    ; Save FCB in case of "*".   [7]
  767. buff    db    80H DUP(?)    ; Use as our DAT.
  768. rdbuf    db    80H DUP(?)
  769. cnt    dw    0
  770. temp    dw    0
  771. temp1   dw      ?               ; Temporary storage.
  772. temp2   dw      ?
  773. temp3   dw      ?
  774. temp4   dw      ?
  775. argblk  dw      ?               ; For subroutine arguments.
  776. argbk1  dw      ?
  777. argbk2  dw      ?
  778. argbk3  dw      ?
  779.  
  780. DATAS   ENDS                    ; End data segment
  781.  
  782.  
  783. MAIN    SEGMENT PARA PUBLIC 'MAIN'
  784. START   PROC  FAR
  785.         ASSUME  CS:MAIN,DS:DATAS,SS:STACK,ES:NOTHING
  786.  
  787.         push ds                 ; Save system data area.
  788.         sub ax,ax               ; Get a zero.
  789.         push ax                 ; Put zero return addr on stack.
  790.  
  791.         mov ax,datas            ; Initialize DS.
  792.         mov ds,ax
  793.     sub ax,ax
  794.  
  795.         mov oldstk,sp           ; Save old stack pointer.
  796.  
  797.         call cmblnk             ; Clear the screen.
  798.     call locate
  799.  
  800.         mov ah,prstr            ; Print the version header.
  801.         mov dx,offset versio
  802.         int dos
  803.  
  804.     mov ah,setdma        ; Set disk transfer address.
  805.     mov dx,offset buff
  806.     int dos
  807.  
  808.     call dobaud        ; Set the baud rate. [19a, 20g]
  809.  
  810. ; This is the main KERMIT loop.  It prompts for and gets the users commands.
  811.  
  812. kermit: mov dx,offset kerm
  813.         call prompt             ; Prompt the user.
  814.         mov dx,offset comtab
  815.         mov bx,offset tophlp
  816.         mov ah,cmkey
  817.         call comnd
  818.          jmp kermt2
  819.         call bx                 ; Call the routine returned.
  820.          jmp kermt3
  821.         cmp extflg,0            ;  Check if the exit flag is set.
  822.         jne krmend              ;  If so jump to KRMEND.
  823.         jmp kermit              ; Do it again.
  824.  
  825. kermt2: mov ah,prstr
  826.         mov dx,offset ermes1    ;  Give an error.
  827.         int dos
  828.         jmp kermit
  829.  
  830. kermt3: mov ah,prstr
  831.         mov dx,offset ermes3    ;  Give an error.
  832.         int dos
  833.         jmp kermit
  834.  
  835. krmend: 
  836.         mov sp,oldstk
  837.         ret
  838.  
  839. START   ENDP
  840.  
  841.  
  842. ; These are some utility routines.
  843.  
  844. ;       Abort
  845.  
  846. ABORT   PROC    NEAR
  847.         mov state,'A'           ; Otherwise abort.
  848.         ret
  849. ABORT   ENDP
  850.  
  851. ;       NAK
  852.  
  853. NAK     PROC    NEAR
  854.         mov ax,pktnum           ; Get the packet number we're waiting for.
  855.         mov argblk,ax
  856.         mov argbk1,0
  857.         mov ah,'N'              ; NAK that packet.
  858.         call spack
  859.      jmp abort
  860.      nop            ; So 'jmp rskp' in SPACK comes here. [19a]
  861.         ret                     ; Go around again.
  862. NAK     ENDP
  863.  
  864. ; Position cursor for an error message.
  865.  
  866. ERPOS    PROC     NEAR
  867. IF ibmpc
  868.     mov ah,2
  869.     mov bh,0
  870.     mov dx,screrr
  871.     int bios
  872.     ret
  873. ENDIF
  874. IF Z100
  875.     mov dx,offset screrr    ; Get address of string to position cursor
  876.     mov ah,prstr        ; Get the function code
  877.     int dos            ; Print the addressing string
  878.     ret            ; And return
  879. ENDIF
  880. ERPOS    ENDP
  881.  
  882. ; Position cursor for number of retries message.
  883.  
  884. RTPOS    PROC     NEAR
  885. IF ibmpc
  886.     mov ah,2
  887.     mov bh,0
  888.     mov dx,scrnrt
  889.     int bios
  890.     ret
  891. ENDIF
  892. IF Z100
  893.     mov ah,prstr        ; Get the function to print string
  894.     mov dx,offset scrnrt    ; Get the address of the string
  895.     int dos            ; Print the string
  896.     ret            ; And return
  897. ENDIF
  898. RTPOS    ENDP
  899.  
  900. ; Reassure user that we acknowledge his ^X/^Z.  [20b]
  901. INTMSG    PROC    NEAR
  902. IF ibmpc            ; Tell user we acknowledge it.
  903.     mov ah,2    
  904.     mov dx,scrint
  905.     mov bh,0
  906.     int bios
  907. ENDIF
  908. IF Z100
  909.     mov ah,prstr        ; Get print string function
  910.     mov dx,offset scrint    ; and string to move cursor
  911.     int dos            ; Print the string
  912. ENDIF
  913.     mov dx,offset infms7    ; File interrupted?
  914.     cmp cxzflg,'X'        ; Yes. 
  915.     je int0
  916.     mov dx,offset infms8    ; File group interrupted.
  917. int0:   mov ah,prstr
  918.         int dos
  919.     ret
  920. INTMSG    ENDP
  921.  
  922. ; Print err message that found a non-standard-Ascii char in the file.
  923.  
  924. BITERR    PROC    NEAR
  925.     push bx
  926. IF ibmpc
  927.     mov ah,2
  928.     mov bh,0
  929.     mov dx,scrhi
  930.     int bios
  931. ENDIF
  932. IF Z100
  933.     mov ah,prstr        ; Get the function to print string
  934.     mov dx,offset scrhi    ; Get the address of the string
  935.     int dos            ; Print the string
  936. ENDIF
  937.     mov ah,prstr
  938.     mov dx,offset hibit
  939.     int dos
  940.     pop bx
  941.     ret
  942. BITERR    ENDP        
  943.  
  944. ;    This routine prints out the escape character in readable format.  
  945.  
  946. ESCPRT    PROC    NEAR        ; [6 start]
  947.     mov dl,escchr
  948.     cmp dl,' '
  949.     jge escpr2
  950.     push dx
  951.     mov ah,prstr
  952.     mov dx,offset esctl
  953.     int dos
  954.     pop dx
  955.     add dl,040H        ; Make it printable.
  956. escpr2:    mov ah,conout
  957.     int dos
  958.     ret
  959. ESCPRT    ENDP            ; [6 end]
  960.  
  961. ;       FCB must be remembered if found "*" in filename.      [7 start]
  962. ;     Copy from place addressed by BX to place addressed by DI.
  963. ;    Also use to get the filename to the FCB from the DTA.
  964.  
  965. FCBCPY    PROC    NEAR
  966. fcbcp1:    cmp cl,0
  967.     je fcbcp2
  968.     mov ah,[bx]
  969.     mov [di],ah
  970.     dec cl
  971.     inc bx
  972.     inc di
  973.     jmp fcbcp1
  974. fcbcp2:    ret
  975. FCBCPY    ENDP    
  976.  
  977. ;       This routine sets up the data for init packet (either the
  978. ;       Send_init or ACK packet).
  979.  
  980. RPAR    PROC    NEAR
  981.         mov ah,rpsiz            ; Get the receive packet size.
  982.         add ah,' '              ; Add a space to make it printable.
  983.         mov [bx],ah             ; Put it in the packet.
  984.         mov ah,rtime            ; Get the receive packet time out.
  985.         add ah,' '              ; Add a space.
  986.         mov 1[bx],ah            ; Put it in the packet.
  987.         mov ah,rpad             ; Get the number of padding chars.
  988.         add ah,' '
  989.         mov 2[bx],ah            ; Put it in the packet.
  990.         mov ah,rpadch           ; Get the padding char.
  991.         add ah,100O             ; Uncontrol it.
  992.         and ah,7FH
  993.         mov 3[bx],ah            ; Put it in the packet.
  994.         mov ah,reol             ; Get the EOL char.
  995.         add ah,' '
  996.         mov 4[bx],ah            ; Put it in the packet.
  997.         mov ah,rquote           ; Get the quote char.
  998.         mov 5[bx],ah            ; Put it in the packet.
  999.         mov ah,06H              ; Six pieces of data.
  1000.         ret
  1001. RPAR    ENDP
  1002.  
  1003. ;       This routine reads in all the send_init packet information.
  1004.  
  1005. SPAR    PROC    NEAR
  1006.         mov temp4,ax            ; Save the number of arguments.
  1007.         mov ah,[bx]             ; Get the max packet size.
  1008.         sub ah,' '              ; Subtract a space.
  1009.         mov spsiz,ah            ; Save it.
  1010.         mov ax,temp4
  1011.         cmp al,3                ; Fewer than three pieces?
  1012.         jge spar1
  1013.         ret                     ; If so we are done.
  1014. spar1:  mov ah,2[bx]            ; Get the number of padding chars.
  1015.         sub ah,' '
  1016.         mov spad,ah
  1017.         mov ax,temp4
  1018.         cmp al,4                ; Fewer than four pieces?
  1019.         jge spar2
  1020.         ret                     ; If so we are done.
  1021. spar2:  mov ah,3[bx]            ; Get the padding char.
  1022.         add ah,100O             ; Re-controlify it.
  1023.         and ah,7FH
  1024.         mov spadch,ah
  1025.         mov ax,temp4
  1026.         cmp al,5                ; Fewer than five pieces?
  1027.         jge spar3
  1028.         ret                     ; If so we are done.
  1029. spar3:  mov ah,4[bx]            ; Get the EOL char.
  1030.         sub ah,' '
  1031.         mov seol,ah
  1032.         mov ax,temp4
  1033.         cmp al,6                ; Fewer than six pieces?
  1034.         jge spar4
  1035.         ret                     ; If so we are done.
  1036. spar4:  mov ah,5[bx]            ; Get the quote char.
  1037.         mov squote,ah
  1038.         ret
  1039. SPAR    ENDP
  1040.  
  1041.  
  1042. ;       Initialize buffers and clear line.
  1043.  
  1044. INIT    PROC    NEAR
  1045.     call cmblnk
  1046.     call locate
  1047.         mov ah,prstr            ; Put statistics headers on the screen.
  1048.         mov dx,offset outlin
  1049.         int dos
  1050.         call init1
  1051.         ret
  1052. INIT    ENDP
  1053.  
  1054. INIT1   PROC    NEAR
  1055.         mov chrcnt,bufsiz              ; Number of chars left.
  1056.         mov bufpnt,offset buff         ; Addr for beginning.
  1057.         ret
  1058. INIT1   ENDP
  1059.  
  1060. ;  Clear out message about interrupted file. [20b]
  1061. CXMSG    PROC    NEAR
  1062. IF ibmpc
  1063.     mov ah,2
  1064.     mov bh,0
  1065.     mov dx,scrint
  1066.     int bios
  1067.     mov ax,0920H
  1068.     mov bx,7
  1069.     mov cx,26
  1070.     int bios    
  1071.     ret
  1072. ENDIF
  1073. IF Z100
  1074.     mov ah,prstr
  1075.     mov dx,offset scrint    ; Move the cursor.
  1076.     int dos
  1077.     mov ah,prstr        ; Get the function again
  1078.     mov dx,offset clreol    ; And the sequence to clear to EOL
  1079.     int dos            ; Do it
  1080.     ret
  1081. ENDIF
  1082. CXMSG    ENDP
  1083.  
  1084. ;  Clear out the old filename on the screen. 
  1085.  
  1086. CLRFLN    PROC    NEAR
  1087. IF ibmpc
  1088.     mov ah,2
  1089.     mov bh,0
  1090.     mov dx,scrfln
  1091.     int bios
  1092.     call clreol        ; Clear to end of line. [19a]
  1093.     ret
  1094. ENDIF
  1095. IF Z100
  1096.     mov ah,prstr        ; Get print string function
  1097.     mov dx,offset scrfln    ; and string to move cursor
  1098.     int dos            ; Print the string
  1099.     mov ah,prstr        ; Get the function again
  1100.     mov dx,offset clreol    ; And the sequence to clear to EOL
  1101.     int dos            ; Do it
  1102.     ret            ; And return
  1103. ENDIF
  1104. CLRFLN    ENDP
  1105.  
  1106. ;       RECEIVE command
  1107.  
  1108. READ    PROC    NEAR
  1109.     mov bx,offset data    ; Where to put text (if any).  [8 start]
  1110.     mov ah,cmtxt
  1111.         call comnd              ; Get text or confirm.
  1112.          jmp kermt3
  1113.     cmp ah,0        ; Read in any chars?
  1114.     je read1        ; A regular receive.
  1115.     mov al,ah
  1116.     mov ah,0
  1117.     mov argbk1,ax        ; Remember number of chars we read.
  1118.     mov ah,'$'        ; Use for printing.
  1119.     mov [bx],ah
  1120.     call init        ; Clear line and initialize buffers.
  1121.     call clrfln        ; Prepare to print filename.
  1122.     mov ah,prstr
  1123.     mov dx,offset data    ; Print file name.
  1124.     int dos
  1125.     mov argblk,0        ; Start at packet zero.
  1126.     mov ah,'R'        ; Receive init packet.
  1127.     call spack        ; Send the packet.
  1128.      jmp kermt3
  1129.     jmp read12                        ; [8 end]
  1130. read1:  call init               ; Clear the line and initialize the buffers.
  1131. read12: mov numpkt,0            ; Set the number of packets to zero.
  1132.         mov numrtr,0            ; Set the number of retries to zero.
  1133.         mov pktnum,0            ; Set the packet number to zero.
  1134.         mov numtry,0            ; Set the number of tries to zero.
  1135.     mov cxzflg,0        ; Reset ^X/^Z flag. [20c] 
  1136.     call serini        ; Initialize serial port. [14]
  1137.         call rtpos        ; Position cursor.
  1138.         mov ax,numrtr
  1139.         call nout               ; Write the number of retries.
  1140.         mov state,'R'           ; Set the state to receive initiate.
  1141. read2:  
  1142. IF ibmpc
  1143.     mov ah,2        ; Position cursor.
  1144.     mov dx,scrst
  1145.     mov bh,0
  1146.     int bios
  1147. ENDIF
  1148. IF Z100
  1149.     mov ah,prstr        ; Get print string function
  1150.     mov dx,offset scrst    ; and string to move cursor
  1151.     int dos            ; Print the string
  1152. ENDIF
  1153.     mov ah,prstr            ; Be informative.
  1154.         mov dx,offset infms1
  1155.         int dos
  1156. IF ibmpc
  1157.     mov ah,2
  1158.     mov dx,scrnp
  1159.     mov bh,0
  1160.     int bios
  1161. ENDIF
  1162. IF Z100
  1163.     mov ah,prstr        ; Get print string function
  1164.     mov dx,offset scrnp    ; and string to move cursor
  1165.     int dos            ; Print the string
  1166. ENDIF
  1167.         mov ax,numpkt
  1168.         call nout               ; Write the number of packets.
  1169.         mov ah,state            ; Get the state.
  1170.         cmp ah,'D'              ; Are we in the data send state?
  1171.         jne read3
  1172.         call rdata
  1173.         jmp read2
  1174. read3:  cmp ah,'F'              ; Are we in the file receive state?
  1175.         jne read4
  1176.         call rfile              ; Call receive file.
  1177.         jmp read2
  1178. read4:  cmp ah,'R'              ; Are we in the receive initiate state?
  1179.         jne read5
  1180.         call rinit
  1181.         jmp read2
  1182. read5:  cmp ah,'C'              ; Are we in the receive complete state?
  1183.         jne read6
  1184.     call serrst        ; Reset serial port. [14]
  1185. IF ibmpc
  1186.     mov ah,2        ; Position cursor.
  1187.     mov dx,scrst
  1188.     mov bh,0
  1189.     int bios
  1190. ENDIF
  1191. IF Z100
  1192.     mov ah,prstr        ; Get print string function
  1193.     mov dx,offset scrst    ; and string to move cursor
  1194.     int dos            ; Print the string
  1195. ENDIF
  1196.         mov ah,prstr
  1197.         mov dx,offset infms3    ; Plus a little cuteness.
  1198.     cmp cxzflg,0        ; Completed or interrupted? [20c]
  1199.     je read13        ; Ended normally. [20c]
  1200.     mov dx,offset infms6    ; Say was interrupted. [20c]
  1201. read13: int dos
  1202.     cmp belflg,0        ; Bell desired?  [17a]
  1203.     je readnb        ; No.  [17a]
  1204.     mov dx,offset ender    ; Ring them bells.    [4]
  1205.     int dos            ; [4]
  1206. readnb:                ; [17a -- new label]
  1207. IF ibmpc
  1208.     mov ah,2
  1209.     mov dx,scrrpr        ; Put prompt here.
  1210.     mov bh,0
  1211.     int bios
  1212. ENDIF
  1213. IF Z100
  1214.     mov ah,prstr        ; Get print string function
  1215.     mov dx,offset scrrpr    ; and string to move cursor
  1216.     int dos            ; Print the string
  1217. ENDIF
  1218.         jmp rskp
  1219. read6:     call serrst        ; Reset serial port. [14]
  1220. IF ibmpc
  1221.     mov ah,2        ; Position cursor.
  1222.     mov dx,scrst
  1223.     mov bh,0
  1224.     int bios
  1225. ENDIF
  1226. IF Z100
  1227.     mov ah,prstr        ; Get print string function
  1228.     mov dx,offset scrst    ; and string to move cursor
  1229.     int dos            ; Print the string
  1230. ENDIF
  1231.         mov ah,prstr
  1232.     mov dx,offset infms4    ; Plus a little cuteness.
  1233.         int dos
  1234.     cmp belflg,0        ; Bell desired?  [17a]
  1235.     je read7        ; No.  [17a]
  1236.     mov dx,offset ender    ; Ring them bells.   [4]
  1237.     int dos            ;  [4]
  1238. read7:
  1239. IF ibmpc
  1240.     mov ah,2
  1241.     mov dx,scrrpr
  1242.     mov bh,0
  1243.     int bios
  1244. ENDIF
  1245. IF Z100
  1246.     mov ah,prstr        ; Get print string function
  1247.     mov dx,offset scrrpr    ; and string to move cursor
  1248.     int dos            ; Print the string
  1249. ENDIF
  1250.         jmp rskp
  1251. READ    ENDP
  1252.  
  1253.  
  1254. ;       Receive routines
  1255.  
  1256. ;       Receive init
  1257.  
  1258. RINIT   PROC    NEAR
  1259.         mov ah,numtry           ; Get the number of tries.
  1260.         cmp ah,imxtry           ; Have we reached the maximum number of tries?
  1261.         jl rinit2
  1262.     call erpos        ; Position cursor.
  1263.         mov dx,offset ermes7
  1264.         mov ah,prstr
  1265.         int dos                 ; Print an error message.
  1266.         jmp abort               ; Change the state to abort.
  1267. rinit2: inc ah                  ; Increment it.
  1268.         mov numtry,ah           ; Save the updated number of tries.
  1269.         call rpack              ; Get a packet.
  1270.          jmp nak                ;  Trashed packet: nak, retry.
  1271.         cmp ah,'S'              ; Is it a send initiate packet?
  1272.         jne rinit3              ; If not see if its an error.
  1273.         mov ah,numtry           ; Get the number of tries.
  1274.         mov oldtry,ah           ; Save it.
  1275.         mov numtry,0            ; Reset the number of tries.
  1276.         mov ax,argblk           ; Returned packet number.  (Synchronize them.)
  1277.         inc ax                  ; Increment it.
  1278.         and ax,3FH              ; Turn off the two high order bits.
  1279.         mov pktnum,ax           ; Save modulo 64 of the number.
  1280.         mov bx,numpkt
  1281.         inc bx                  ; Increment the number of packets.
  1282.         mov numpkt,bx
  1283.         mov ax,argbk1           ; Get the number of arguments received.
  1284.         mov bx,offset data      ; Get a pointer to the data.
  1285.         call spar               ; Get the data into the proper variables.
  1286.         mov bx,offset data      ; Get a pointer to our data block.
  1287.         call rpar               ; Set up the receive parameters.
  1288.     xchg ah,al
  1289.     mov ah,0
  1290.         mov argbk1,ax           ; Store the returned number of arguments.
  1291.         mov ah,'Y'              ; Acknowledge packet.
  1292.         call spack              ; Send the packet.
  1293.      jmp abort
  1294.         mov ah,'F'              ; Set the state to file send.
  1295.         mov state,ah
  1296.         ret
  1297. rinit3: cmp ah,'E'              ; Is it an error packet?
  1298.         jne rinit4
  1299.         call error
  1300. rinit4: jmp abort
  1301. RINIT   ENDP
  1302.  
  1303.  
  1304. ;       Receive file
  1305.  
  1306. RFILE   PROC    NEAR
  1307.         cmp numtry,maxtry       ; Have we reached the maximum number of tries?
  1308.         jl rfile1
  1309.     call erpos        ; Position cursor.
  1310.         mov dx,offset ermes8
  1311.         mov ah,prstr
  1312.         int dos                 ; Print an error message.
  1313.         jmp abort               ; Change the state to abort.
  1314. rfile1: inc numtry              ; Save the updated number of tries.
  1315.         call rpack              ; Get a packet.
  1316.          jmp nak                ;  Trashed packet: nak, retry.
  1317.         cmp ah,'S'              ; Is it a send initiate packet?
  1318.         jne rfile2              ;  No, try next type.
  1319.         cmp oldtry,imxtry       ; Have we reached the maximum number of tries?
  1320.         jl rfil12               ; If not proceed.
  1321.     call erpos        ; Position cursor.
  1322.         mov dx,offset ermes7
  1323.         mov ah,prstr
  1324.         int dos                 ; Print an error message.
  1325.         jmp abort               ; Change the state to abort.
  1326. rfil12: inc oldtry              ; Save the updated number of tries.
  1327.         mov ax,pktnum           ; Get the present packet number.
  1328.     cmp ax,0        ; Had we wrapped around? [18 start]
  1329.     jne rfilx 
  1330.     mov ax,64
  1331. rfilx:  dec ax                  ; Decrement.  [18 end -- new label]
  1332.         cmp ax,argblk           ; Is the packet's number one less than now?
  1333.         je rfil13
  1334.         jmp nak                 ; No, NAK and try again.
  1335. rfil13: call rtpos              ; Position cursor.
  1336.         inc numrtr              ; Increment the number of retries.
  1337.         mov ax,numrtr
  1338.         call nout               ; Write the number of retries.
  1339.         mov numtry,0            ; Reset the number of tries.
  1340.         mov bx,offset data      ; Get a pointer to our data block.
  1341.         call rpar               ; Set up the parameter information.
  1342.     xchg ah,al
  1343.     mov ah,0
  1344.         mov argbk1,ax           ; Save the number of arguments.
  1345.         mov ah,'Y'              ; Acknowledge packet.
  1346.         call spack              ; Send the packet.
  1347.      jmp abort
  1348.         ret
  1349. rfile2: cmp ah,'Z'              ; Is it an EOF packet?
  1350.         jne rfile3              ;  No, try next type.
  1351.         cmp oldtry,maxtry       ; Have we reached the maximum number of tries?
  1352.         jl rfil21               ; If not proceed.
  1353.         call erpos              ; Position cursor.
  1354.         mov dx,offset ermes9
  1355.         mov ah,prstr
  1356.         int dos                 ; Print an error message.
  1357.         jmp abort               ; Change the state to abort.
  1358. rfil21: inc oldtry              ; Increment it.
  1359.         mov ax,pktnum           ; Get the present packet number.
  1360.     cmp ax,0        ; Had we wrapped around? [18 start]
  1361.     jne rfily
  1362.     mov ax,64
  1363. rfily:  dec ax                  ; Decrement.  [18 end -- new label]
  1364.         cmp ax,argblk           ; Is the packet's number one less than now?
  1365.         je rfil24
  1366.         jmp nak                 ; No, NAK and try again.
  1367. rfil24: call rtpos              ; Position cursor.
  1368.         inc numrtr              ; Increment the number of retries
  1369.         mov ax,numrtr
  1370.         call nout               ; Write the number of retries.
  1371.         mov numtry,0
  1372.         mov argbk1,0            ; No data.  (The packet number is in argblk.)
  1373.         mov ah,'Y'              ; Acknowledge packet.
  1374.         call spack              ; Send the packet.
  1375.      jmp abort
  1376.         ret
  1377. rfile3: cmp ah,'F'              ; Start of file?
  1378.         jne rfile4
  1379.         mov ax,argblk           ; Get the packet number.
  1380.         cmp ax,pktnum           ; Is it the right packet number?
  1381.         je rfil32
  1382.         jmp nak                 ; No, NAK it and try again.
  1383. rfil32: inc ax                  ; Increment the packet number.
  1384.         and ax,3FH              ; Turn off the two high order bits.
  1385.         mov pktnum,ax           ; Save modulo 64 of the number.
  1386.         inc numpkt              ; Increment the number of packets.
  1387.         call gofil              ; Get a file to write to.
  1388.          jmp abort
  1389.         call init1              ; Initialize all the buffers.
  1390.         mov ah,numtry           ; Get the number of tries.
  1391.         mov oldtry,ah           ; Save it.
  1392.         mov numtry,0            ; Reset the number of tries.
  1393.         mov argbk1,0            ; No data.  (The packet number is in argblk.)
  1394.         mov ah,'Y'              ; Acknowledge packet.
  1395.         call spack              ; Send the packet.
  1396.      jmp abort
  1397.         mov state,'D'           ; Set the state to data receive.
  1398.         ret
  1399. rfile4: cmp ah,'B'              ; End of transmission.
  1400.         jne rfile5
  1401.         mov ax,pktnum
  1402.         cmp ax,argblk           ; Do we match?
  1403.         je rfil41
  1404.         jmp nak                 ; No, NAK it and try again.
  1405. rfil41: mov argbk1,0            ; No data.  (Packet number already in argblk).
  1406.         mov ah,'Y'              ; Acknowledge packet.
  1407.         call spack              ; Send the packet.
  1408.      jmp abort
  1409.         mov state,'C'           ; Set the state to complete.
  1410.         ret
  1411. rfile5: cmp ah,'E'              ; Is it an error packet.
  1412.         jne rfile6
  1413.         call error
  1414. rfile6: jmp abort
  1415. RFILE   ENDP
  1416.  
  1417.  
  1418. ;       Receive data
  1419.  
  1420. RDATA   PROC    NEAR
  1421.         cmp numtry,maxtry       ; Get the number of tries.
  1422.         jl rdata1
  1423.         call erpos              ; Position cursor.
  1424.         mov dx,offset erms10
  1425.         mov ah,prstr
  1426.         int dos                 ; Print an error message.
  1427.         jmp abort               ; Change the state to abort.
  1428. rdata1: inc numtry              ; Save the updated number of tries.
  1429.         call rpack              ; Get a packet.
  1430.          jmp nak                ;  Trashed packet: nak, retry.
  1431.         cmp ah,'D'              ; Is it a data packet?
  1432.     je rdat11
  1433.         jmp rdata2              ;  No, try next type.
  1434. rdat11: mov ax,pktnum           ; Get the present packet number.
  1435.         cmp ax,argblk           ; Is the packet's number correct?
  1436.         jz rdat14
  1437.         cmp oldtry,maxtry       ; Have we reached the maximum number of tries?
  1438.         jl rdat12               ; If not proceed.
  1439.     call erpos              ; Position cursor.
  1440.         mov dx,offset erms10
  1441.         mov ah,prstr
  1442.         int dos                 ; Print an error message.
  1443.         jmp abort               ; Change the state to abort.
  1444. rdat12: inc oldtry              ; Save the updated number of tries.
  1445. ;        dec pktnum              ; Decrement present packet number.  [14]
  1446.         mov ax,pktnum
  1447.     cmp ax,0        ; Had we wrapped around? [18 start]
  1448.     jne rdatx
  1449.     mov ax,64
  1450. rdatx:    dec ax            ; [14] [18 end -- new label]
  1451.         cmp ax,argblk           ; Is the packet's number one less than now?
  1452.         je rdat13
  1453.         jmp nak                 ; No, NAK it and try again.
  1454. rdat13: call rtpos              ; Position cursor.
  1455.         inc numrtr              ; Increment the number of retries
  1456.         mov ax,numrtr
  1457.         call nout               ; Write the number of retries.
  1458.         mov numtry,0            ; Reset number of tries.
  1459.         mov argbk1,0            ; No data.  (The packet number is in argblk.)
  1460.         mov ah,'Y'              ; Acknowledge packet.
  1461.         call spack              ; Send the packet.
  1462.      jmp abort
  1463.         ret
  1464. rdat14: inc ax                  ; Increment the packet number.
  1465.         and ax,3FH              ; Turn off the two high order bits.
  1466.         mov pktnum,ax           ; Save modulo 64 of the number.
  1467.         inc numpkt              ; Increment the number of packets.
  1468.         mov ah,numtry           ; Get the number of tries.
  1469.         mov oldtry,ah           ; Save it.
  1470.         mov ax,argbk1           ; Get the length of the data.
  1471.     cmp cxzflg,0        ; Has the user typed a ^X or ^Z? [20c]
  1472.     jne rdat15        ; If yes don't write data out to file. [20c]
  1473.     call ptchr
  1474.          jmp abort              ;  Unable to write out chars; abort.
  1475. rdat15: mov numtry,0            ; Reset the number of tries.
  1476.         mov argbk1,0            ; No data.  (Packet number still in argblk.)
  1477.     cmp cxzflg,0        ; Interrupt file transfer? [20c]
  1478.     je rdat16        ; Nope. [20c] 
  1479.     mov bx,offset data    ; Send data in ACK in case remote... [20c] 
  1480.     mov ah,cxzflg        ; ... knows about ^X/^Z. [20c]
  1481.     mov [bx],ah        ; Put data into the packet. [20c]
  1482.     mov argbk1,1        ; Set data size to 1. [20c]
  1483. rdat16: mov ah,'Y'              ; Acknowledge packet.
  1484.         call spack              ; Send the packet.
  1485.      jmp abort
  1486.         ret
  1487. rdata2: cmp ah,'F'              ; Start of file?
  1488.         jne rdata3              ;  No, try next type.
  1489.         cmp oldtry,maxtry       ; Have we reached the maximum number of tries?
  1490.         jl rdat21               ; If not proceed.
  1491.     call erpos        ; Position cursor.
  1492.         mov dx,offset ermes8
  1493.         mov ah,prstr
  1494.         int dos                 ; Print an error message.
  1495.         jmp abort               ; Change the state to abort.
  1496. rdat21: inc oldtry              ; Save the updated number of tries.
  1497.         mov ax,pktnum
  1498.     cmp ax,0        ; Had we wrapped around? [18 start]
  1499.     jne rdaty
  1500.     mov ax,64
  1501. rdaty:    dec ax            ; [14 Omitted accidentally - D.T.] [18 end]
  1502.         cmp ax,argblk           ; Is the packet's number one less than now?
  1503.         je rdat22
  1504.         jmp nak                 ; No, NAK it and try again.
  1505. rdat22: call rtpos              ; Position cursor.
  1506.         inc numrtr              ; Increment the number of retries
  1507.         mov ax,numrtr
  1508.         call nout               ; Write the number of retries.
  1509.         mov numtry,0            ; Reset number of tries.
  1510.         mov argbk1,0            ; No data.  (The packet number is in argblk.)
  1511.         mov ah,'Y'              ; Acknowledge packet.
  1512.         call spack              ; Send the packet.
  1513.      jmp abort
  1514.         ret
  1515. rdata3: cmp ah,'Z'              ; Is it a EOF packet?
  1516.     je rdat3x                ; [13]
  1517.         jmp rdata4               ; Try and see if its an error. [13]
  1518. rdat3x: mov ax,pktnum           ; Get the present packet number. [13]
  1519.         cmp ax,argblk           ; Is the packet's number correct?
  1520.         je rdat32
  1521.         jmp nak                 ; No, NAK it and try again.
  1522. rdat32: inc ax                  ; Increment the packet number.
  1523.         and ax,3FH              ; Turn off the two high order bits.
  1524.         mov pktnum,ax           ; Save modulo 64 of the number.
  1525.         inc numpkt
  1526.     cmp cxzflg,0        ; Do we want to discard the file? [20c]
  1527.     jne rdt32x        ; Yes. [20c]
  1528.     cmp argbk1,1        ; One piece of data? [20c]
  1529.     jne rdat33        ; Nope - finish writing out file? [20c]
  1530.     mov bx,offset data    ; Get data area. [20c]
  1531.     mov ah,[bx]        ; Get the data. [20c]
  1532.     cmp ah,'D'        ; "D" for discard? [20c]
  1533.     jne rdat33        ; Nope - write out file. [20c]
  1534. rdt32x:    mov ah,delf        ; Delete the file if opened. [20c]
  1535.     mov dx,offset fcb    ; Give the file parameters. [20c]
  1536.     int dos            ; Kill it, ignore errors. [20c]
  1537.     cmp cxzflg,'X'        ; Kill one file or all? [20c]
  1538.     jne rdat36        ; No so leave flag alone. [20c]
  1539.     call cxmsg        ; Clear msg about interrupt. [20c]
  1540.     mov cxzflg,0        ; Reset - ^X only kills one file. [20c]
  1541.     jmp rdat36
  1542. rdat33: mov bx,bufpnt           ; Get the dma pointer.
  1543.     mov ax,80H
  1544.         sub ax,chrcnt           ; Get the number of chars left in the DMA.
  1545.     cmp ax,80H        ;   [13 start]
  1546.     jne rdat34
  1547.     call outbuf        ; Write out buffer if no room for ^Z.
  1548.      jmp abort
  1549.     mov ax,0        ;   [13 end]
  1550. rdat34: mov cl,'Z'-100O         ; Put in a ^Z for EOF.
  1551.         mov [bx],cl
  1552.     inc ax
  1553.     dec chrcnt
  1554.     mov cx,chrcnt
  1555.     mov temp,cx
  1556.     inc bx
  1557. rdt3:    inc ax
  1558.     cmp ax,80H
  1559.     jg rdat35        ; Pad till full.
  1560.     mov cl,0        ; Use nulls.
  1561.     mov [bx],cl
  1562.     inc bx
  1563.         jmp rdt3
  1564. rdat35: call outbuf             ; Output the last buffer.
  1565.          jmp abort              ;  Give up if the disk is full.
  1566.     call fixfcb
  1567.         mov ah,closf            ; Close up the file.
  1568.         mov dx,offset fcb
  1569.         int dos
  1570. rdat36: mov ah,numtry           ; Get the number of tries.
  1571.         mov oldtry,ah           ; Save it.
  1572.         mov numtry,0            ; Reset the number of tries.
  1573.         mov argbk1,0            ; No data.  (The packet number is in argblk.)
  1574.         mov ah,'Y'              ; Acknowledge packet.
  1575.         call spack              ; Send the packet.
  1576.      jmp abort
  1577.         mov state,'F'
  1578.         ret
  1579. rdata4: cmp ah,'E'                      ; Is it an error packet.
  1580.         jne rdata5
  1581.         call error
  1582. rdata5: jmp abort
  1583. RDATA   ENDP
  1584.  
  1585. FIXFCB  PROC    NEAR    
  1586.     mov bx,offset fcb+18
  1587.     mov di,offset filsiz
  1588.     mov ax,[bx]
  1589.     mov [di],ax
  1590.     mov bx,offset fcb+16
  1591.     mov ax,[bx]
  1592.     mov 2[di],ax
  1593.     mov ax,temp        ; Get number of chars in last buffer full.
  1594.     sub filsiz+2,ax        ; Get real file size.
  1595.     sbb filsiz,0
  1596.     mov bx,offset fcb+18
  1597.     mov di,offset filsiz
  1598.     mov ax,[di]
  1599.     mov [bx],ax
  1600.     mov bx,offset fcb+16
  1601.     mov ax,2[di]
  1602.     mov [bx],ax
  1603.     ret
  1604. FIXFCB    ENDP
  1605.  
  1606.  
  1607. ;       Send command
  1608.  
  1609. SEND    PROC    NEAR
  1610.         mov ah,cmifi            ; Parse an input file spec.
  1611.         mov dx,offset fcb       ; Give the address for the FCB.
  1612.         call comnd
  1613.          jmp r                  ;  Give up on bad parse.
  1614. send1:  mov ah,cmcfm
  1615.         call comnd              ; Get a confirm.
  1616.          jmp r                  ;  Didn't get a confirm.
  1617. send11: mov ah,sfirst           ; Get the first file.
  1618.         mov dx,offset fcb
  1619.         int dos
  1620.         cmp al,0FFH             ; Any found?
  1621.         jne send12
  1622.     mov ah,prstr
  1623.     mov dx,offset crlf
  1624.     int dos
  1625.         mov ah,prstr
  1626.         mov dx,offset erms15
  1627.         int dos
  1628.         ret
  1629. send12: cmp wldflg,0        ; Any wildcards.      [7 start]
  1630.     je send16        ; Nope, so no problem.
  1631.     mov bx,offset fcb    ; Remember what FCB looked like.
  1632.     mov di,offset cpfcb
  1633.     mov cl,37        ; Size of FCB.
  1634.     call fcbcpy
  1635.     mov di,offset fcb+1    ; Copy filename    from DTA to FCB.
  1636.     mov bx,offset buff+1
  1637.     mov cl,11
  1638.     call fcbcpy                    ; [7 end]
  1639. send16: call init               ; Clear the line and initialize the buffers.
  1640.     call serini        ; Initialize serial port. [14]
  1641.         mov pktnum,0            ; Set the packet number to zero.
  1642.         mov numtry,0            ; Set the number of tries to zero.
  1643.         mov numpkt,0            ; Set the number of packets to zero.
  1644.         mov numrtr,0            ; Set the number of retries to zero.
  1645.         call rtpos              ; Position cursor.
  1646.         mov ax,0
  1647.         call nout               ; Write the number of retries.
  1648.         mov state,'S'           ; Set the state to receive initiate.
  1649. send2:  
  1650. IF ibmpc 
  1651.     mov ah,2                ; Position cursor.
  1652.     mov bh,0
  1653.     mov dx,scrst
  1654.     int bios
  1655. ENDIF
  1656. IF Z100
  1657.     mov ah,prstr        ; Get print string function
  1658.     mov dx,offset scrst    ; and string to move cursor
  1659.     int dos            ; Print the string
  1660. ENDIF
  1661.         mov ah,prstr            ; Be informative.
  1662.         mov dx,offset infms2
  1663.         int dos
  1664. IF ibmpc
  1665.     mov ah,2
  1666.     mov dx,scrnp
  1667.     mov bh,0
  1668.     int bios
  1669. ENDIF
  1670. IF Z100
  1671.     mov ah,prstr        ; Get print string function
  1672.     mov dx,offset scrnp    ; and string to move cursor
  1673.     int dos            ; Print the string
  1674. ENDIF
  1675.         mov ax,numpkt
  1676.         call nout               ; Write the packet number.
  1677.         cmp state,'D'           ; Are we in the data send state?
  1678.         jne send3
  1679.         call sdata
  1680.         jmp send2
  1681. send3:  cmp state,'F'           ; Are we in the file send state?
  1682.         jne send4
  1683.         call sfile              ; Call send file.
  1684.         jmp send2
  1685. send4:  cmp state,'Z'           ; Are we in the EOF state?
  1686.         jne send5
  1687.         call seof
  1688.         jmp send2
  1689. send5:  cmp state,'S'           ; Are we in the send initiate state?
  1690.         jne send6
  1691.         call sinit
  1692.         jmp send2
  1693. send6:  cmp state,'B'           ; Are we in the eot state?
  1694.         jne send7
  1695.         call seot
  1696.         jmp send2
  1697. send7:  cmp state,'C'           ; Are we in the send complete state?
  1698.         jne send8
  1699.     call serrst        ; Reset serial port.  [14]
  1700. IF ibmpc
  1701.     mov ah,2                ; Position cursor.
  1702.     mov dx,scrst
  1703.     mov bh,0
  1704.     int bios
  1705. ENDIF
  1706. IF Z100
  1707.     mov ah,prstr        ; Get print string function
  1708.     mov dx,offset scrst    ; and string to move cursor
  1709.     int dos            ; Print the string
  1710. ENDIF
  1711.         mov ah,prstr
  1712.         mov dx,offset infms3    ; Plus a little cuteness.
  1713.     cmp cxzflg,0        ; Completed or interrupted? [20b]
  1714.     je snd71        ; Ended normally. [20b]
  1715.     mov dx,offset infms6    ; Say was interrupted. [20b]
  1716. snd71:  int dos            ; New label. [20b] 
  1717.     cmp belflg,0        ; Bell desired? [17a]
  1718.     je sendnb        ; [17a]
  1719.     mov dx,offset ender    ; Ring them bells.   [4]
  1720.     int dos            ;  [4]
  1721. sendnb:                ; [17a -- new label] 
  1722. IF ibmpc
  1723.     mov ah,2
  1724.     mov dx,scrrpr
  1725.     mov bh,0
  1726.     int bios
  1727. ENDIF
  1728. IF Z100
  1729.     mov ah,prstr        ; Get print string function
  1730.     mov dx,offset scrrpr    ; and string to move cursor
  1731.     int dos            ; Print the string
  1732. ENDIF
  1733.         jmp rskp
  1734. send8:     call serrst        ; Reset serial port.  [14]
  1735. IF ibmpc
  1736.     mov ah,2                ; Position cursor.
  1737.     mov dx,scrst
  1738.     mov bh,0
  1739.     int bios
  1740. ENDIF
  1741. IF Z100
  1742.     mov ah,prstr        ; Get print string function
  1743.     mov dx,offset scrst    ; and string to move cursor
  1744.     int dos            ; Print the string
  1745. ENDIF
  1746.         mov ah,prstr
  1747.         mov dx,offset infms4    ; Plus a little cuteness.
  1748.         int dos
  1749.     cmp belflg,0        ; Bell desired?  [17a]
  1750.     je send9        ; No.  [17a]
  1751.     mov dx,offset ender    ; Ring them bells.   [4]
  1752.     int dos            ;  [4]
  1753. send9:
  1754. IF ibmpc
  1755.     mov ah,2
  1756.     mov dx,scrrpr
  1757.     mov bh,0
  1758.     int bios
  1759. ENDIF
  1760. IF Z100
  1761.     mov ah,prstr        ; Get print string function
  1762.     mov dx,offset scrrpr    ; and string to move cursor
  1763.     int dos            ; Print the string
  1764. ENDIF
  1765.         jmp rskp
  1766. SEND    ENDP
  1767.  
  1768.  
  1769. ;       Send routines
  1770.  
  1771. ;       Send initiate
  1772.  
  1773.  
  1774. SINIT   PROC    NEAR
  1775.         cmp numtry,imxtry       ; Have we reached the maximum number of tries?
  1776.         jl sinit2
  1777.     call erpos
  1778.         mov dx,offset erms14
  1779.         mov ah,prstr
  1780.         int dos                 ; Print an error message.
  1781.         jmp abort               ; Change the state to abort.
  1782. sinit2: inc numtry              ; Save the updated number of tries.
  1783.         mov bx,offset data      ; Get a pointer to our data block.
  1784.         call rpar               ; Set up the parameter information.
  1785.     xchg ah,al
  1786.     mov ah,0
  1787.         mov argbk1,ax           ; Save the number of arguments.
  1788.         mov ax,numpkt           ; Get the packet number.
  1789.         mov argblk,ax
  1790.         mov ah,'S'              ; Send initiate packet.
  1791.         call spack              ; Send the packet.
  1792.      jmp abort
  1793.         call rpack              ; Get a packet.
  1794.          jmp r                  ;  Trashed packet don't change state, retry.
  1795.         cmp ah,'Y'              ; ACK?
  1796.         jne sinit3              ; If not try next.
  1797.         mov ax,pktnum           ; Get the packet number.
  1798.         cmp ax,argblk           ; Is it the right packet number?
  1799.         je sini22
  1800.         ret                     ; If not try again.
  1801. sini22: inc ax                  ; Increment the packet number.
  1802.         and ax,3FH              ; Turn off the two high order bits.
  1803.         mov pktnum,ax           ; Save modulo 64 of the number.
  1804.         inc numpkt              ; Increment the number of packets.
  1805.         mov ax,argbk1           ; Get the number of pieces of data.
  1806.         mov bx,offset data      ; Pointer to the data.
  1807.         call spar               ; Read in the data.
  1808.         mov ah,numtry           ; Get the number of tries.
  1809.         mov oldtry,ah           ; Save it.
  1810.         mov numtry,0            ; Reset the number of tries.
  1811.         mov state,'F'           ; Set the state to file send.
  1812.         call getfil             ; Open the file.
  1813.          jmp abort              ;  Something is wrong, die.
  1814.         ret
  1815. sinit3: cmp ah,'N'              ; NAK?
  1816.         jne sinit4              ; If not see if its an error.
  1817.         call rtpos              ; Position cursor.
  1818.         inc numrtr              ; Increment the number of retries
  1819.         mov ax,numrtr
  1820.         call nout               ; Write the number of retries.
  1821. ;        mov ax,pktnum           ; Get the present packet number. [18 start]
  1822. ;        inc ax                  ; Increment.
  1823. ;        cmp ax,argblk           ; Get the packet's number.
  1824. ;        je sini32
  1825. ;        ret                     ; If not assume its for this packet, go again.
  1826. ;sini32: mov numtry,0            ; Reset number of tries.
  1827. ;        mov state,'F'           ; Set the state to file send. [18 end]
  1828.         ret
  1829. sinit4: cmp ah,'E'              ; Is it an error packet.
  1830.         jne sinit5
  1831.         call error
  1832. sinit5: jmp abort
  1833. SINIT   ENDP
  1834.  
  1835.  
  1836.  
  1837. ;       Send file header
  1838.  
  1839. SFILE   PROC    NEAR
  1840.         cmp numtry,maxtry       ; Have we reached the maximum number of tries?
  1841.         jl sfile1
  1842.     call erpos
  1843.         mov dx,offset erms14
  1844.         mov ah,prstr
  1845.         int dos                 ; Print an error message.
  1846.         jmp abort               ; Change the state to abort.
  1847. sfile1: inc numtry              ; Increment it.
  1848.     mov cxzflg,0        ; Clear ^X,^Z flag.  [20b]
  1849.         mov datptr,offset data  ; Get a pointer to our data block.
  1850.     mov bx,offset fcb+1        ; Pointer to file name in FCB.
  1851.     mov fcbptr,bx        ; Save position in FCB.
  1852.     mov cl,0        ; Counter for chars in file name.
  1853.     mov ch,0        ; Counter for number of chars in FCB.
  1854. sfil11:    cmp ch,8H        ; Ninth char?
  1855.     jne sfil12
  1856.     mov ah,'.'
  1857.     mov bx,datptr
  1858.     mov [bx],ah        ; Put dot in data packet.    
  1859.     inc bx
  1860.     mov datptr,bx        ; Save new position in data packet.
  1861.     inc cl
  1862. sfil12:    inc ch
  1863.     cmp ch,0CH        ; Twelve?
  1864.     jns sfil13
  1865.     mov bx,fcbptr
  1866.     mov ah,[bx]        ; Get char of filename.
  1867.     inc bx
  1868.     mov fcbptr,bx        ; Save position in FCB.
  1869.     cmp ah,'!'        ; Is it a good char?
  1870.     jl sfil11        ; If not, get the next.
  1871.     mov bx,datptr
  1872.     mov [bx],ah        ; Put char in data buffer.
  1873.     inc cl            ; Increment counter.
  1874.     inc bx
  1875.     mov datptr,bx        ; Save new position. 
  1876.     jmp sfil11        ; Get another char.
  1877. sfil13: mov ch,0
  1878.     mov argbk1,cx        ; Save number of char in filename.
  1879.     mov bx,datptr
  1880.     mov ah,'$'
  1881.     mov [bx],ah        ; Put dollar sign for printing.
  1882.     call clrfln
  1883.     mov ah,prstr
  1884.     mov dx,offset data    ; Print file name.
  1885.     int dos
  1886.  
  1887.         mov ax,pktnum           ; Get the packet number.
  1888.         mov argblk,ax
  1889.         mov ah,'F'              ; File header packet.
  1890.         call spack              ; Send the packet.
  1891.      jmp abort
  1892.         call rpack              ; Get a packet.
  1893.          jmp r                  ;  Trashed packet don't change state, retry.
  1894.         cmp ah,'Y'              ; ACK?
  1895.         jne sfile2              ; If not try next.
  1896.         mov ax,pktnum           ; Get the packet number.
  1897.         cmp ax,argblk
  1898.         je sfil14
  1899.         ret                     ; If not hold out for the right one.
  1900. sfil14: inc ax                  ; Increment the packet number.
  1901.         and ax,3FH              ; Turn off the two high order bits.
  1902.         mov pktnum,ax           ; Save modulo 64 of the number.
  1903.         inc numpkt              ; Increment the number of packets.
  1904.         mov ah,numtry           ; Get the number of tries.
  1905.         mov oldtry,ah           ; Save it.
  1906.         mov numtry,0            ; Reset the number of tries.
  1907.  
  1908. sfil15: mov ah,0                ; Get a zero.
  1909.         mov bx,offset fcb
  1910.         add bx,20H
  1911.         mov [bx],ah             ; Set the record number to zero.
  1912.         mov eoflag,ah           ; Indicate not EOF.
  1913.         mov ah,0FFH
  1914.         mov filflg,ah           ; Indicate file buffer empty.
  1915.         call gtchr
  1916.          jmp sfil16             ; Error go see if its EOF.
  1917.         jmp sfil17              ; Got the chars, proceed.
  1918. sfil16: cmp ah,0FFH             ; Is it EOF?
  1919.         je sfl161
  1920.         jmp abort               ; If not give up.
  1921. sfl161: mov ah,'Z'              ; Set the state to EOF.
  1922.         mov state,ah
  1923.         ret
  1924. sfil17: mov siz,ax
  1925.  
  1926.         mov state,'D'           ; Set the state to data send.
  1927.         ret
  1928. sfile2: cmp ah,'N'              ; NAK?
  1929.         jne sfile3              ; Try if error packet.
  1930.         call rtpos              ; Position cursor.
  1931.         inc numrtr              ; Increment the number of retries
  1932.         mov ax,numrtr
  1933.         call nout               ; Write the number of retries.
  1934.         mov ax,pktnum           ; Get the present packet number.
  1935.         inc ax                  ; Increment.
  1936.     and ax,03FH        ; Account for wraparound.  [18]
  1937.     cmp ax,argblk           ; Is the packet's number one more than now?
  1938.         jz sfil14               ; Just as good as a ACK; go to the ACK code.
  1939.         ret                     ; If not go try again.
  1940. sfile3: cmp ah,'E'              ; Is it an error packet.
  1941.         jne sfile4
  1942.         call error
  1943. sfile4: jmp abort
  1944. SFILE   ENDP
  1945.  
  1946.  
  1947. ;       Send data
  1948.  
  1949. SDATA   PROC    NEAR
  1950.     cmp cxzflg,0        ; Have we seen ^X or ^Z? [20b]
  1951.     je sdata0        ; Nope, just continue. [20b]
  1952.     mov state,'Z'        ; Else, abort sending the file. [20b]
  1953.     ret
  1954. sdata0: cmp numtry,maxtry       ; Have we reached the maximum number of tries?
  1955.         jl sdata1
  1956.     call erpos
  1957.         mov dx,offset erms14
  1958.         mov ah,prstr
  1959.         int dos                 ; Print an error message.
  1960.         jmp abort               ; Change the state to abort.
  1961. sdata1: inc numtry              ; Increment it.
  1962.         mov datptr,offset data  ; Get a pointer to our data block.
  1963.         mov cbfptr,offset filbuf ; Pointer to chars to be sent.
  1964.         mov cx,1                ; First char.
  1965. sdat11: mov bx,cbfptr
  1966.         mov ah,[bx]
  1967.         inc cbfptr
  1968.         mov bx,datptr
  1969.         mov [bx],ah             ; Put the char in the data packet.
  1970.         inc datptr              ; Save position in data packet.
  1971.         inc cx                  ; Increment the count.
  1972.         cmp cx,siz              ; Have we transfered that many?
  1973.         jle sdat11              ; If not get another.
  1974.         mov ax,siz              ; Number of char in char buffer.
  1975.         mov argbk1,ax
  1976.         mov ax,pktnum           ; Get the packet number.
  1977.         mov argblk,ax
  1978.         mov ah,'D'              ; Data packet.
  1979.         call spack              ; Send the packet.
  1980.      jmp abort
  1981.         call rpack              ; Get a packet.
  1982.          jmp r                  ;  Trashed packet don't change state, retry.
  1983.         cmp ah,'Y'              ; ACK?
  1984.         jne sdata2              ; If not try next.
  1985.         mov ax,pktnum           ; Get the packet number.
  1986.         cmp ax,argblk           ; Is it the right packet number?
  1987.         jz sdat12
  1988.         ret                     ; If not hold out for the right one.
  1989. sdat12: inc ax                  ; Increment the packet number.
  1990.         and ax,3FH              ; Turn off the two high order bits.
  1991.         mov pktnum,ax           ; Save modulo 64 of the number.
  1992.         inc numpkt              ; Increment the number of packets.
  1993.         mov ah,numtry           ; Get the number of tries.
  1994.         mov oldtry,ah           ; Save it.
  1995.         mov numtry,0            ; Reset the number of tries.
  1996.     cmp argbk1,1        ; Does the ACK contain data? [20b]
  1997.     jne sdt12x        ; Nope, so continue. [20b]
  1998.     mov bx,offset data    ; If yes, check the data field. [20b]
  1999.     mov ah,[bx]        ; Pick it up. [20b]
  2000.     cmp ah,'X'        ; Other side requests ^X? [20b]
  2001.     jne sdt12y        ; Nope. [20b]
  2002.     jmp sdt12z        ; And leave. [20b]
  2003. sdt12y: cmp ah,'Z'        ; Other side requests ^Z? [20b]
  2004.     jne sdt12x        ; Nope. [20b]
  2005. sdt12z:    mov cxzflg,ah        ; Yes remember it. [20b]
  2006.     mov state,'Z'        ; Abort sending file(s). [20b]
  2007.     ret
  2008. sdt12x: call gtchr
  2009.          jmp sdat13             ; Error go see if its EOF.
  2010.         mov siz,ax              ; Save the size of the data gotten.
  2011.         ret
  2012.  
  2013. sdat13: cmp ah,0FFH             ; Is it EOF?
  2014.         je sdt131
  2015.         jmp abort               ; If not give up.
  2016.  
  2017. sdt131: mov state,'Z'           ; Set the state to EOF.
  2018.         ret
  2019. sdata2: cmp ah,'N'              ; NAK?
  2020.         jne sdata3              ; See if is an error packet.
  2021.         call rtpos            ; Position cursor.
  2022.         inc numrtr              ; Increment the number of retries
  2023.         mov ax,numrtr
  2024.         call nout               ; Write the number of retries.
  2025.         mov ax,pktnum           ; Get the present packet number.
  2026.         inc ax                  ; Increment.
  2027.     and ax,03FH        ; Account for wraparound.  [18]
  2028.         cmp ax,argblk           ; Is the packet's number one more than now?
  2029.         jz sdat12               ; Just as good as ACK; goto ACK code.
  2030.         ret                     ; If not go try again.
  2031. sdata3: cmp ah,'E'              ; Is it an error packet.
  2032.         jne sdata4
  2033.         call error
  2034. sdata4: jmp abort
  2035. SDATA   ENDP
  2036.  
  2037.  
  2038. ;       Send EOF
  2039.  
  2040. SEOF    PROC    NEAR
  2041.         cmp numtry,maxtry       ; Have we reached the maximum number of tries?
  2042.         jl seof1
  2043.         call erpos              ; Position cursor.
  2044.         mov dx,offset erms14
  2045.         mov ah,prstr
  2046.         int dos                 ; Print an error message.
  2047.         jmp abort               ; Change the state to abort.
  2048. seof1:  inc numtry              ; Increment it.
  2049.         mov ax,pktnum           ; Get the packet number.
  2050.         mov argblk,ax
  2051.         mov argbk1,0            ; No data.
  2052.     cmp cxzflg,0        ; Seen a ^X or ^Z? [20b]
  2053.     je seof11        ; Nope, send normal EOF packet. [20b]
  2054.     mov bx,offset data    ; Get data area of packet.
  2055.     mov ah,'D'        ; Use "D" for discard. [20b]
  2056.     mov [bx],ah        ; And add it to the packet. [20b]
  2057.     mov argbk1,1        ; Set data size to 1. [20b]
  2058. seof11: mov ah,'Z'              ; EOF packet.
  2059.         call spack              ; Send the packet.
  2060.      jmp abort
  2061.         call rpack              ; Get a packet.
  2062.          jmp r                  ;  Trashed packet don't change state, retry.
  2063.         cmp ah,'Y'              ; ACK?
  2064.         jne seof2               ; If not try next.
  2065.         mov ax,pktnum           ; Get the packet number.
  2066.         cmp ax,argblk           ; Is it the right packet number?
  2067.         jz seof12
  2068.         ret                     ; If not hold out for the right one.
  2069. seof12: inc ax                  ; Increment the packet number.
  2070.         and ax,3FH              ; Turn off the two high order bits.
  2071.         mov pktnum,ax           ; Save modulo 64 of the number.
  2072.         inc numpkt              ; Increment the number of packets.
  2073.         mov ah,numtry           ; Get the number of tries.
  2074.         mov oldtry,ah           ; Save it.
  2075.         mov numtry,0            ; Reset the number of tries.
  2076.         mov ah,closf            ; Close the file.
  2077.         mov dx,offset fcb
  2078.         int dos
  2079.         call gtnfil             ; Get the next file.
  2080.          jmp seof13             ;  No more.
  2081.         mov state,'F'           ; Set the state to file send.
  2082.     cmp cxzflg,'X'        ; Control-X seen? [20b]
  2083.     jne seof14
  2084.     call cxmsg        ; Clear out the interrupt msg. [20b]
  2085. seof14:    mov cxzflg,0        ; Reset the flag. [20b]
  2086.         ret
  2087. seof13: mov state,'B'           ; Set the state to EOT.
  2088.         ret
  2089. seof2:  cmp ah,'N'              ; NAK?
  2090.         jne seof3               ; Try and see if its an error packet.
  2091.         call rtpos              ; Position cursor.
  2092.         inc numrtr              ; Increment the number of retries
  2093.         mov ax,numrtr
  2094.         call nout               ; Write the number of retries.
  2095.         mov ax,pktnum           ; Get the present packet number.
  2096.         inc ax                  ; Increment.
  2097.     and ax,03FH        ; Account for wraparound.  [18]
  2098.         cmp ax,argblk           ; Is the packet's number one more than now?
  2099.         jz seof12               ; Just as good as a ACK; go to the ACK code.
  2100.         ret                     ; If not go try again.
  2101. seof3:  cmp ah,'E'              ; Is it an error packet?
  2102.         jne seof4
  2103.         call error
  2104. seof4:  jmp abort
  2105. SEOF    ENDP
  2106.  
  2107.  
  2108. ;       Send EOT
  2109.  
  2110. SEOT    PROC    NEAR
  2111.         cmp numtry,maxtry       ; Have we reached the maximum number of tries?
  2112.         jl seot1
  2113.         call erpos             ; Position cursor.
  2114.         mov dx,offset erms14
  2115.         mov ah,prstr
  2116.         int dos                 ; Print an error message.
  2117.         jmp abort               ; Change the state to abort.
  2118. seot1:  inc numtry              ; Increment it.
  2119.         mov ax,pktnum           ; Get the packet number.
  2120.         mov argblk,ax
  2121.         mov argbk1,0            ; No data.
  2122.         mov ah,'B'              ; EOF packet.
  2123.         call spack              ; Send the packet.
  2124.      jmp abort
  2125.         call rpack              ; Get a packet.
  2126.          jmp r                  ; Trashed packet don't change state, retry.
  2127.         cmp ah,'Y'              ; ACK?
  2128.         jne seot2               ; If not try next.
  2129.         mov ax,pktnum           ; Get the packet number.
  2130.         cmp ax,argblk           ; Is it the right packet number?
  2131.         jz seot12
  2132.         ret                     ; If not hold out for the right one.
  2133. seot12: inc ax                  ; Increment the packet number.
  2134.         and ax,3FH              ; Turn off the two high order bits.
  2135.         mov pktnum,ax           ; Save modulo 64 of the number.
  2136.         inc numpkt              ; Increment the number of packets.
  2137.         mov ah,numtry           ; Get the number of tries.
  2138.         mov oldtry,ah           ; Save it.
  2139.         mov numtry,0            ; Reset the number of tries.
  2140.         mov state,'C'           ; Set the state to file send.
  2141.         ret
  2142. seot2:  cmp ah,'N'              ; NAK?
  2143.         jne seot3               ; Is it error.
  2144.         call rtpos              ; Position cursor.
  2145.         inc numrtr              ; Increment the number of retries
  2146.         mov ax,numrtr
  2147.         call nout               ; Write the number of retries.
  2148.         mov ax,pktnum           ; Get the present packet number.
  2149.         inc ax                  ; Increment.
  2150.     and ax,03FH        ; Account for wraparound.  [18]
  2151.         cmp ax,argblk           ; Is the packet's number one more than now?
  2152.         jz seot12               ; Just as good as a ACK; go to the ACK code.
  2153.         ret                     ; If not go try again.
  2154. seot3:  cmp ah,'E'              ; Is it an error packet.
  2155.         jne seot4
  2156.         call error
  2157. seot4:  jmp abort
  2158. SEOT    ENDP
  2159.  
  2160.  
  2161. ; Here is the bulk of the file I/O.  Good luck.
  2162. ;       File routines
  2163.  
  2164. ;       Output the chars in a packet.
  2165.  
  2166. FILEIO    PROC    NEAR     
  2167.  
  2168. ptchr:  mov temp1,ax            ; Save the size.
  2169.         mov bx,offset data      ; Beginning of received packet data.
  2170.         mov outpnt,bx           ; Remember where we are.
  2171.         mov ch,rquote        ; Quote char.
  2172. ptchr1: dec temp1               ; Decrement # of chars in packet.
  2173.     jnl pt1
  2174.         jmp rskp                ; Return successfully if done.
  2175. pt1:    dec chrcnt              ; Decrement number of chars in dta.
  2176.         jns ptchr2              ; Continue if space left.
  2177.         call outbuf             ; Output it if full.
  2178.          jmp r                  ;  Error return if disk is full.
  2179. ptchr2: mov bx,outpnt           ; Get position in output buffer.
  2180.         mov ah,[bx]                     ; Grab a char.
  2181.         inc bx
  2182.         mov outpnt,bx           ; and bump pointer.
  2183.         cmp ah,ch               ; Is it the quote char?
  2184.         jne ptchr4              ; If not proceed.
  2185.         mov ah,[bx]                     ; Get the quoted character
  2186.         inc bx
  2187.         mov outpnt,bx           ; and bump pointer.
  2188.         dec temp1               ; Decrement # of chars in packet.
  2189.         mov dh,ah               ; Save the char.
  2190.         and ah,80H                      ; Turn off all but the parity bit.
  2191.         mov dl,ah               ; Save the parity bit.
  2192.         mov ah,dh                       ; Get the char.
  2193.         and ah,7FH                      ; Turn off the parity bit.
  2194.         cmp ah,ch               ; Is it the quote char?
  2195.         jz ptchr3               ; If so just go write it out.
  2196.         mov ah,dh                       ; Get the char.
  2197.         add ah,40H                      ; Make it a control char again.
  2198.         and ah,7FH                      ; Modulo 128.
  2199. ptchr3: or ah,dl                ; Or in the parity bit.
  2200. ptchr4: mov bx,bufpnt           ; Destination buffer.
  2201.         mov [bx],ah                     ; Store it.
  2202.         inc bx
  2203.         mov bufpnt,bx           ; Update the pointer
  2204.         jmp ptchr1              ; and loop to next char.
  2205.  
  2206.  
  2207.         ; output the buffer, reset bufpnt and chrcnt
  2208.  
  2209. outbuf: push bx
  2210.         mov ah,writef           ; The write code.
  2211.         mov dx,offset fcb
  2212.         int dos                ; Write the record.
  2213.         pop bx
  2214.         cmp al,0                ; Successful.
  2215.         jz outbf1
  2216.     push ax            ; Remember the return code. [20d]
  2217.     call abfil        ; Fix things up before aborting. [20d]
  2218.     pop ax            ; Retrive return code. [20d]
  2219.     cmp al,01
  2220.     jz outbf0
  2221.     call erpos
  2222.     mov ah,prstr
  2223.     mov dx,offset erms17    ; Record length exceeds dta.
  2224.     int dos
  2225.     ret
  2226. outbf0: call erpos
  2227.     mov ah,prstr            ; Tell about it.
  2228.         mov dx,offset erms11    ; Disk full error.
  2229.         int dos
  2230.         ret
  2231. outbf1: mov bx,offset buff      ; Addr for beginning.
  2232.         mov bufpnt,bx           ; Store addr for beginning.
  2233.         mov ax,bufsiz-1         ; Buffer size.
  2234.         mov chrcnt,ax           ; Number of chars left.
  2235.         jmp rskp
  2236.  
  2237. ;  Tidy up before aborting.    [20d]
  2238. ABFIL    PROC    NEAR
  2239.     mov ah,closf        ; Close the file.
  2240.     mov dx,offset fcb
  2241.     int dos
  2242.     cmp abfflg,1        ; Delete what got across or keep it?
  2243.     jne abfil0        ; Nope, keep it.
  2244.     mov ah,delf        ; Delete it.
  2245.     mov dx,offset fcb
  2246.     int dos
  2247. abfil0:    mov bx,offset erms10    ; Text of message to send.
  2248.     call errpack        ; Send an error packet.
  2249.     ret
  2250. ABFIL    ENDP
  2251.  
  2252. ; General routine for sending an error packet.  Register BX should
  2253. ; point to the text of the message being sent in the packet. [20f]
  2254.  
  2255. ERRPACK    PROC    NEAR
  2256.     mov di,offset data    ; Where to put the message.
  2257.     mov al,0
  2258. errp1:    mov ah,[bx]
  2259.     cmp ah,'$'        ; At end of message?
  2260.     je errp2
  2261.     inc al            ; Remember number of chars in msg.
  2262.     mov [di],ah
  2263.     inc bx
  2264.     inc di
  2265.     jmp errp1
  2266. errp2:    mov ah,0
  2267.     mov argbk1,ax
  2268.     mov ah,'E'        ; And send an error packet.
  2269.     call spack
  2270.      ret            ; Return if succeed or fail.
  2271.     nop
  2272.     nop
  2273.     ret
  2274. ERRPACK    ENDP
  2275.  
  2276. ;       Get the chars from the file.
  2277.  
  2278. gtchr:  mov ch,squote           ; Keep quote char in c.
  2279.         mov ah,filflg           ; Get the file flag.
  2280.         cmp ah,0                        ; Is there anything in the DMA?
  2281.         jz gtchr0               ; Yup, proceed.
  2282.         mov cl,0                ; No chars yet.
  2283.         call inbuf
  2284.          jmp gtceof             ; No more chars, go return EOF.
  2285. gtchr0: mov al,spsiz            ; Get the maximum packet size.
  2286.         sub al,5                ; Subtract the overhead.
  2287.         mov ah,0
  2288.         mov temp1,ax            ; Number of chars we're to get.
  2289.         mov bx,offset filbuf            ; Where to put the data.
  2290.         mov cbfptr,bx           ; Remember where we are.
  2291.         mov cl,0                ; No chars.
  2292. gtchr1: dec temp1               ; Decrement the number of chars left.
  2293.         jns gtchr2              ; Go on if there is more than one left.
  2294.         mov al,cl                       ; Return the count in A.
  2295.     mov ah,0
  2296.         jmp rskp
  2297. gtchr2: mov ax,chrcnt
  2298.         dec ax
  2299.         jl gtchr3
  2300.         mov chrcnt,ax
  2301.         jmp gtchr4
  2302. gtchr3: call inbuf              ; Get another buffer full.
  2303.          jmp gtceof
  2304.     cmp chrcnt,0
  2305.     jne gtchr4
  2306.     sub cl,2        ; Don't count controllified Z.
  2307.     mov al,cl
  2308.     mov ah,0
  2309.     jmp rskp
  2310. gtchr4: mov bx,bufpnt           ; Position in DMA.
  2311.         mov ah,[bx]                     ; Get a char from the file.
  2312.         inc bx
  2313.         mov bufpnt,bx
  2314.         mov dh,ah               ; Save the char.
  2315.         and ah,80H                      ; Turn off all but parity.
  2316.         mov dl,ah               ; Save the parity bit.
  2317.         mov ah,dh                       ; Restore the char.
  2318.         and ah,7FH                      ; Turn off the parity.
  2319.         cmp ah,' '                      ; Compare to a space.
  2320.         jl gtchr5               ; If less then its a control char, handle it.
  2321.         cmp ah,del                      ; Is the char a delete?
  2322.         jz gtchr5               ; Go quote it.
  2323.         cmp ah,ch               ; Is it the quote char?
  2324.         jne gtchr8              ; If not proceed.
  2325.         dec temp1               ; Decrement the char total remaining.
  2326.         mov bx,cbfptr           ; Position in character buffer.
  2327.         mov [bx],ah                     ; Put the char in the buffer.
  2328.         inc bx
  2329.         mov cbfptr,bx
  2330.         inc cl                  ; Increment the char count.
  2331.         jmp gtchr8
  2332. gtchr5: or ah,dl                ; Turn on the parity bit.
  2333.         cmp ah,('Z'-100O)               ; Is it a ^Z?
  2334.         jne gtchr7              ; If not just proceed.
  2335.         mov ah,eoflag           ; EOF flag set?
  2336.         cmp ah,0
  2337.         jz gtchr6               ; If not just go on.
  2338.         mov bx,bufpnt
  2339.         mov ax,chrcnt
  2340.         mov dh,al               ; Get number of chars left in DMA.
  2341. gtch51: dec dh
  2342.         mov ah,dh
  2343.         jns gtch52              ; Any chars left?
  2344.         mov chrcnt,0            ; If not, say so.
  2345.         mov al,cl                       ; Return the count in A.
  2346.     mov ah,0
  2347.         jmp rskp
  2348. gtch52: mov ah,[bx]                     ; Get the next char.
  2349.         inc bx                  ; Move the pointer.
  2350.         cmp ah,('Z'-100O)               ; Is it a ^Z?
  2351.         jz gtch51               ; If so see if they rest are.
  2352.  
  2353. gtchr6: mov ah,('Z'-100O)       ; Restore the ^Z.
  2354. gtchr7: xchg ah,al
  2355.         mov ah,0
  2356.         mov temp2,ax            ; Save the char.
  2357.         dec temp1               ; Decrement char counter.
  2358.         mov bx,cbfptr           ; Position in character buffer.
  2359.         mov [bx],ch                     ; Put the quote in the buffer.
  2360.         inc bx
  2361.         mov cbfptr,bx
  2362.         inc cl                  ; Increment the char count.
  2363.         mov ax,temp2            ; Get the control char back.
  2364.         xchg al,ah
  2365.         add ah,40H                      ; Make the non-control.
  2366.         and ah,7fH                      ; Modulo 200 octal.
  2367. gtchr8: mov bx,cbfptr           ; Position in character buffer.
  2368.         or ah,dl                ; Or in the parity bit.
  2369.         mov [bx],ah                     ; Put the char in the buffer.
  2370.         inc bx
  2371.         mov cbfptr,bx
  2372.         inc cl                  ; Increment the char count.
  2373.         jmp gtchr1              ; Go around again.
  2374.  
  2375. gtceof: cmp cl,0        ; Had we gotten any data?
  2376.     je gteof0        ; Nope.
  2377.     mov al,cl
  2378.     mov ah,0
  2379.     jmp rskp
  2380. gteof0: mov ah,0FFH             ; Get a minus one.
  2381.         ret
  2382.  
  2383.  
  2384. inbuf:  mov ah,eoflag           ; Have we reached the end?
  2385.         cmp ah,0
  2386.         jz inbuf0
  2387.         ret                     ; Return if set.
  2388. inbuf0: push bx                 
  2389.     push cx
  2390.     mov bx,offset buff      ; Set the r/w buffer pointer.
  2391.         mov bufpnt,bx
  2392.         mov ah,readf            ; Read a record.
  2393.         mov dx,offset fcb
  2394.         int dos
  2395.     mov cx,filsiz
  2396.     cmp cx,0        ; Check for 128 chars or less left.
  2397.     jne inbuf1        ; Still have data left.
  2398.     mov ax,ds
  2399.     mov es,ax
  2400.     mov si,offset filsiz+2
  2401.     mov di,offset bufhex
  2402.     cmps filsiz+2,es:bufhex
  2403.     ja inbuf1        ; More than 128 chars.
  2404.     mov eoflag,0FFH        ; Set End-of-file.
  2405.     mov cx,filsiz+2
  2406.     mov chrcnt,cx        ; Return proper number of chars.
  2407.         mov filflg,0        ; Buffer not empty.
  2408.     pop cx
  2409.     pop bx
  2410.     jmp rskp
  2411. inbuf1:    sub filsiz+2,80H    ; Sent another 128 chars.
  2412.     sbb filsiz,0        ; Account for the doubleword.
  2413.     mov al,80H        ; Use as counter for number of chars read.
  2414.     pop cx
  2415.     pop bx
  2416.     cmp filflg,0        ; Ever used DMS?
  2417.     jnz inbf21        ; Nope, then don't change count.
  2418.     dec al            ; Fix boundary error.
  2419. inbf21: mov ah,0                ; Zero the flag (buffer not empty).
  2420.     mov chrcnt,ax        ; Number of chars read from file.
  2421.         mov filflg,0        ; Buffer not empty.
  2422.     jmp rskp
  2423.  
  2424. getfil: mov ah,0FFH
  2425.         mov filflg,ah           ; Nothing in the DMA.
  2426.         mov ax,0
  2427.         mov eoflag,ah           ; Not the end of file.
  2428.         mov bx,offset fcb+0CH
  2429.         mov [bx],ax             ; Zero the current block number.
  2430.         mov bx,offset fcb+0EH
  2431.         mov [bx],ax             ; Ditto for Lrecl.
  2432.         mov bx,offset fcb+20H
  2433.         mov [bx],ah             ; Zero the current record (of block).
  2434.     inc bx
  2435.     mov [bx],ax        ; Same for record (of file). 
  2436.     mov bx,offset fcb+23H
  2437.     mov [bx],ax
  2438.         mov ah,openf            ; Open the file.
  2439.         mov dx,offset fcb
  2440.         int dos
  2441.     mov bx,offset fcb+18    ; File size in bytes (hi order word).
  2442.     mov di,offset filsiz    ; Where to put the info. 
  2443.     mov ax,[bx]
  2444.     mov [di],ax
  2445.     mov bx,offset fcb+16    ; Lo order word.
  2446.     mov ax,[bx]
  2447.     mov 2[di],ax
  2448.     sub filsiz+2,1        ; Don't count the ^Z.
  2449.     sbb filsiz,0
  2450.         jmp rskp
  2451.  
  2452.  
  2453. gtnfil: cmp cxzflg,'Z'        ; Did we have a ^Z? [20b]
  2454.     je gtn5            ; If yes, we're done sending files. [20b]
  2455.     cmp wldflg,0        ; Was there a "*"?        [7 start]
  2456.     je gtn5            ; Nope.
  2457.     mov bx,offset cpfcb    ; Get FCB from last check for file.  
  2458.     mov di,offset fcb    ; Copy to FCB.
  2459.     mov cl,37        ; Size of FCB.
  2460.     call fcbcpy
  2461. gtn2:    mov ah,snext
  2462.     mov dx,offset fcb    ; More files?
  2463.     int dos
  2464.     cmp al,0FFH
  2465.     je gtn5
  2466.     mov bx,offset fcb
  2467.     mov di,offset cpfcb
  2468.     mov cl,37
  2469.     call fcbcpy        ; Copy from FCB.
  2470.     mov di,offset fcb+1    ; Get name of next file to send.
  2471.     mov bx,offset buff+1
  2472.     mov cl,11
  2473.     call fcbcpy
  2474.     call getfil        ; Initialize
  2475.      jmp r
  2476.     jmp rskp            
  2477. gtn5:    mov wldflg,0        ; Reset wild card flag.
  2478.     ret                         ;  [7 end]
  2479.  
  2480.  
  2481. ;       Get the file name (including host to micro translation)
  2482.  
  2483. gofil:  mov bx,offset data      ; Get the address of the file name.
  2484.         mov datptr,bx           ; Store the address.
  2485.         mov bx,offset fcb+1            ; Address of the FCB.
  2486.         mov fcbptr,bx           ; Save it.
  2487.         mov ax,0
  2488.         mov temp1,ax            ; Initialize the char count.
  2489.         mov temp2,ax
  2490.     mov si,offset fcb
  2491.         mov [si],ah             ; Set the drive to default to current.
  2492.         mov ch,' '
  2493. gofil1: mov [bx],ch                     ; Blank the FCB.
  2494.         inc bx
  2495.         inc ah
  2496.         cmp ah,0BH                      ; Twelve?
  2497.         jl gofil1
  2498. gofil2: mov bx,datptr           ; Get the NAME field.
  2499.         mov ah,[bx]
  2500.         inc bx
  2501.         mov datptr,bx
  2502.         cmp ah,'.'                      ; Seperator?
  2503.         jne gofil3
  2504.         mov bx,offset fcb+9H
  2505.         mov fcbptr,bx
  2506.         mov ax,temp1
  2507.         mov temp2,ax
  2508.         mov temp1,9H
  2509.         jmp gofil6
  2510. gofil3: cmp ah,0                        ; Trailing null?
  2511.         jz gofil7               ; Then we're done.
  2512.         mov bx,fcbptr
  2513.         mov [bx],ah
  2514.         inc bx
  2515.         mov fcbptr,bx
  2516.         mov ax,temp1            ; Get the char count.
  2517.         inc ax
  2518.         mov temp1,ax
  2519.         cmp ax,8H                       ; Are we finished with this field?
  2520.         jl gofil2
  2521. gofil4: mov temp2,ax
  2522.         mov bx,datptr
  2523.         mov ah,[bx]
  2524.         inc bx
  2525.         mov datptr,bx
  2526.         cmp ah,0
  2527.         jz gofil7
  2528.         cmp ah,'.'                      ; Is this the terminator?
  2529.         jne gofil4              ; Go until we find it.
  2530. gofil6: mov bx,datptr           ; Get the TYPE field.
  2531.         mov ah,[bx]
  2532.         inc bx
  2533.         mov datptr,bx
  2534.         cmp ah,0                        ; Trailing null?
  2535.         jz gofil7               ; Then we're done.
  2536.         mov bx,fcbptr
  2537.         mov [bx],ah
  2538.         inc bx
  2539.         mov fcbptr,bx
  2540.         inc temp1               ; Increment char count.
  2541.         cmp temp1,0CH                   ; Are we finished with this field?
  2542.         jl gofil6
  2543. gofil7: mov bx,datptr
  2544.     mov ah,'$'
  2545.         mov [bx],ah             ; Put in a dollar sign for printing.
  2546.     call clrfln
  2547.         mov ah,prstr            ; Print the file name.
  2548.         mov dx,offset data
  2549.         int dos
  2550.         mov ah,flwflg           ; Is file warning on?
  2551.         cmp ah,0
  2552.     jnz gf7x
  2553.         jmp gofil9              ; If not, just proceed.
  2554. gf7x:   mov ah,openf            ; See if the file exists.
  2555.         mov dx,offset fcb
  2556.         int dos
  2557.         cmp al,0FFH             ; Does it exist?
  2558.     jnz gf8x
  2559.         jmp gofil9               ; If not create it.
  2560. gf8x:    
  2561. IF ibmpc
  2562.     mov ah,2        ; Position cursor.
  2563.     mov dx,scrfr
  2564.     mov bh,0
  2565.     int bios
  2566. ENDIF
  2567. IF Z100
  2568.     mov ah,prstr        ; Get print string function
  2569.     mov dx,offset scrfr    ; and string to move cursor
  2570.     int dos            ; Print the string
  2571. ENDIF
  2572.         mov ah,prstr            ; Inform the user we are renaming the file.
  2573.         mov dx,offset infms5
  2574.         int dos
  2575.         mov ax,temp2            ; Get the number of chars in the file name.
  2576.         cmp ax,0
  2577.         jne gofil8
  2578.         mov ax,temp1
  2579.         mov temp2,ax
  2580. gofil8: mov ch,0
  2581.         mov cl,al
  2582.     mov al,0            ; Says if first field is full.
  2583.         cmp cl,9H                       ; Is the first field full?
  2584.         jne gofl81
  2585.         mov al,0FFH             ; Set a flag saying so.
  2586.         dec cl
  2587. gofl81: mov bx,offset fcb              ; Get the FCB.
  2588.         add bx,cx               ; Add in the character number.
  2589.     mov ah,'&'
  2590.         mov [bx],ah             ; Replace the char with an ampersand.
  2591.     push ax
  2592.         push bx
  2593.         mov ah,openf            ; See if the file exists.
  2594.         mov dx,offset fcb
  2595.         int dos
  2596.         pop bx
  2597.         cmp al,0FFH             ; Does it exist?
  2598.     pop ax
  2599.         jz gofl89               ; If not create it.
  2600.         cmp al,0                      ; Get the flag.
  2601.         jz gofl83
  2602.         dec cl                  ; Decrement the number of chars.
  2603.         cmp cl,0
  2604.         jz gofl88               ; If no more, die.
  2605.         jmp gofl81
  2606. gofl83: inc cl                  ; Increment the number of chars.
  2607.         cmp cl,9H                       ; Are we to the end?
  2608.         jl gofl81               ; If not try again ; else fail. 
  2609.  
  2610. gofl88: call erpos        ; Position cursor.
  2611.     mov ah,prstr            ; Tell the user that we can't rename it.
  2612.         mov dx,offset ermes4
  2613.         int dos
  2614.     mov bx,dx        ; Tell host can't rename.  [20f]
  2615.     call errpack        ; Send error packet before abort. [20f]
  2616.         ret
  2617.  
  2618. gofl89: mov bx,offset fcb+0CH          ; Point past the end of the file name.
  2619.         mov dh,[bx]                     ; Save the present contents.
  2620.     mov ah,'$'
  2621.         mov [bx],ah             ; Put in a dollar sign.
  2622.         push dx
  2623.         mov ah,prstr            ; Print the file name.
  2624.         mov dx,offset fcb+1
  2625.         int dos
  2626.         pop dx
  2627.         mov bx,offset fcb+0CH          ; Restore over the dollar sign.
  2628.         mov [bx],dh
  2629. gofil9: mov ah,delf             ; Delete the file if it exists.
  2630.         mov dx,offset fcb
  2631.         int dos
  2632.         mov ax,0
  2633.         mov si,offset fcb+0CH
  2634.         mov [si],ax             ; Zero current block.
  2635.         mov si,offset fcb+0EH
  2636.         mov [si],ax             ; Same for Lrecl.
  2637.         mov si,offset fcb+20H
  2638.         mov [si],ah             ; Zero the current record (within block).
  2639.     inc si
  2640.     mov [si],ax        ; Zero record (within file).
  2641.     mov si,offset fcb+23H
  2642.     mov [si],ax
  2643.         mov ah,makef            ; Now create it.
  2644.         mov dx,offset fcb
  2645.         int dos
  2646.         cmp al,0FFH             ; Is the disk full?
  2647.     je gf9x
  2648.         jmp rskp
  2649. gf9x:   call erpos        ; Position cursor.
  2650.     mov ah,prstr            ; If so tell the user.
  2651.         mov dx,offset erms11
  2652.         int dos
  2653.         ret
  2654.  
  2655. FILEIO    ENDP
  2656.  
  2657.  
  2658. ;       Packet routines
  2659.  
  2660. ; Send_Packet
  2661. ; This routine assembles a packet from the arguments given and sends it
  2662. ; to the host.
  2663. ;
  2664. ; Expects the following:
  2665. ;       AH     - Type of packet (D,Y,N,S,R,E,F,Z,T)
  2666. ;       ARGBLK - Packet sequence number
  2667. ;       ARGBK1 - Number of data characters
  2668. ; Returns: +1 always
  2669.  
  2670. SPKT    PROC    NEAR
  2671.  
  2672. spack:     push ax                 ; Save the packet type.
  2673. IF ibmpc
  2674.     call clrbuf        ; Clear the input buffer. [20e]
  2675. ENDIF
  2676.         mov bx,offset packet    ; Get address of the send packet.
  2677.         mov ah,soh              ; Get the start of header char.
  2678.         mov [bx],ah             ; Put in the packet.
  2679.         inc bx                  ; Point to next char.
  2680.         mov ax,argbk1           ; Get the number of data chars.
  2681.     xchg ah,al
  2682.         add ah,' '+3            ; Real packet character count made printable.
  2683.         mov [bx],ah             ; Put in the packet.
  2684.         inc bx                  ; Point to next char.
  2685.         mov cl,ah               ; Start the checksum.
  2686.         mov ax,argblk           ; Get the packet number.
  2687.     xchg ah,al
  2688.         add ah,' '              ; Add a space so the number is printable.
  2689.         mov [bx],ah             ; Put in the packet.
  2690.         inc bx                  ; Point to next char.
  2691.         add cl,ah               ; Add the packet number to the checksum.
  2692.         pop ax                  ; Get the packet type.
  2693.         mov [bx],ah             ; Put in the packet.
  2694.         inc bx                  ; Point to next char.
  2695.         add cl,ah               ; Add the type to the checksum.
  2696.         mov dx,argbk1           ; Get the packet size.
  2697. spack2: cmp dx,0                ; Are there any chars of data?
  2698.          jz spack3              ;  No, finish up.
  2699.         dec dx                  ; Decrement the char count.
  2700.         mov ah,[bx]             ; Get the next char.
  2701.         inc bx                  ; Point to next char.
  2702.         add cl,ah               ; Add the char to the checksum.
  2703.     cmp ah,0
  2704.     jns spack2
  2705.     mov hierr,0FFH        ; set err flag. 
  2706.         jmp spack2              ; Go try again.
  2707. spack3: cmp hierr,0
  2708.     je sp3x            ; Nothing special to do.
  2709.     call biterr
  2710.     mov hierr,0        ; Reset.
  2711. sp3x:    mov ah,cl               ; Get the character total.
  2712.     mov ch,cl        ; Save here too (need 'cl' for shift).
  2713.         and ah,0C0H             ; Turn off all but the two high order bits.
  2714.     mov cl,6
  2715.         shr ah,cl               ; Shift them into the low order position.
  2716.     mov cl,ch
  2717.         add ah,cl               ; Add it to the old bits.
  2718.         and ah,3FH              ; Turn off the two high order bits.  (MOD 64)
  2719.         add ah,' '              ; Add a space so the number is printable.
  2720.         mov [bx],ah             ; Put in the packet.
  2721.         inc bx                  ; Point to next char.
  2722.         mov ah,seol             ; Get the EOL the other host wants.
  2723.         mov [bx],ah             ; Put in the packet.
  2724.         inc bx                  ; Point to next char.
  2725.         mov ah,0                ; Get a null.
  2726.         mov [bx],ah             ; Put in the packet.
  2727.     cmp debug,0        ; debug mode.
  2728.     je spack4
  2729.     inc bx
  2730.     mov ah,'$'
  2731.     mov [bx],ah
  2732. IF ibmpc    
  2733.     mov ah,2
  2734.     mov dx,scrsp
  2735.     mov bh,0
  2736.     int bios
  2737. ENDIF
  2738. IF Z100
  2739.     mov ah,prstr        ; Get print string function
  2740.     mov dx,offset scrsp    ; and string to move cursor
  2741.     int dos            ; Print the string
  2742. ENDIF
  2743.     mov ah,prstr
  2744.     mov dx,offset spmes
  2745.     int dos
  2746.     mov dx,offset packet
  2747.     mov ah,prstr
  2748.     int dos            ; debug end.
  2749. spack4: call outpkt             ; Call the system dependent routine.
  2750.      jmp r
  2751.     jmp rskp
  2752.  
  2753. SPKT    ENDP 
  2754. ;       Write out a packet.
  2755.  
  2756. OUTPKT  PROC    NEAR
  2757.         mov dh,spad             ; Get the number of padding chars.
  2758. outpk2: dec dh
  2759.         cmp dh,0
  2760.         jl outpk3               ; If none left proceed.
  2761.         mov ah,spadch           ; Get the padding char.
  2762.         call outchr             ; Output it.
  2763.         jmp outpk2
  2764. outpk3: mov bx,offset packet    ; Point to the packet.
  2765. outlup: mov ah,[bx]             ; Get the next character.
  2766.         cmp ah,0                ; Is it a null?
  2767.         jnz outlp2
  2768.         jmp rskp
  2769. outlp2: call outchr             ; Output the character.
  2770.      jmp r
  2771.         inc bx                  ; Increment the char pointer.
  2772.         jmp outlup
  2773. OUTPKT  ENDP
  2774.  
  2775.  
  2776. ;************************System Dependent****************************
  2777. ;       Put a char in AH to the port.
  2778. PORT    PROC  NEAR 
  2779. IF ibmpc
  2780. outchr:    sub cx,cx        ; [14 start]
  2781.     mov al,ah        ; Parity routine works on AL. [16]
  2782.     call dopar        ; Set parity appropriately.     [10]
  2783.     mov ah,al        ; Don't overwrite character with status. [16]
  2784.     mov dx,mdstat        ; Get port status. [19b]
  2785. outch1:    in al,dx
  2786.     test al,20H        ; Transmitter ready?
  2787.     jnz outch2        ; Yes
  2788.     loop outch1
  2789.      jmp r            ; Timeout
  2790. outch2:    mov al,ah        ; Now send it out
  2791.     mov dx,mddat        ; [19b]
  2792.     out dx,al
  2793.     jmp rskp        ; [14 end]
  2794. ENDIF
  2795. IF Z100
  2796. outchr:    mov al,ah        ; Yes, get the character into al
  2797.     mov cx,0
  2798.     call dopar        ; Set parity appropriately.   [10]
  2799. outch1:    call bios_auxout    ; Send the character
  2800.     jmp rskp
  2801. ENDIF
  2802.  
  2803. ;************************System Dependent****************************
  2804. ;
  2805. ;       Get a char from the port and return in AH.
  2806.  
  2807. inchr:  
  2808. IF ibmpc
  2809.     call prtchr        ; Get character if ready.  [14]
  2810.      jmp inchr3        ; Got it in AL.  [14]
  2811. ENDIF
  2812. IF Z100
  2813.      push    bx        ; Save BX
  2814.     mov ah,chr_status    ; Get the function
  2815.     mov al,chr_sfgs        ; And the subfunction
  2816.     call bios_auxfunc    ; Determine if anything to input
  2817.     cmp bl,0        ; Is there?
  2818.     jnz inchr3        ; Yes, go get it
  2819.     pop bx            ; And restore BX
  2820. ENDIF
  2821.         mov ah,constat          ; Is a char on the console?
  2822.         int dos
  2823.         cmp al,0
  2824.         jz inchr                ; If not go look for another char.
  2825.         mov ah,conin            ; Get the char.
  2826.         int dos
  2827.     mov ah,al 
  2828.         cmp ah,cr                       ; Is it a carriage return?
  2829.         je inchr4               ; If yes, then leave.
  2830.     cmp ah,'Z'-100O        ; Control-Z? [20b]
  2831.     je inchr2        ; Yes - flag it. [20b]
  2832.     cmp ah,'X'-100O        ; Control-X? [20b]
  2833.     je inchr2        ; Yes - flag it. [20b]
  2834.     jmp inchr        ; Wait for some kind of input.
  2835. inchr2: add ah,100O        ; Make it printable. [20b]
  2836.     mov cxzflg,ah        ; Remember what we saw. [20b]
  2837.     jmp inchr        ; Continue getting input. [20b]
  2838. inchr4:    ret
  2839. inchr3: 
  2840. IF Z100
  2841.     mov ah,chr_read        ; Get the function to read
  2842.     call bios_auxfunc    ; Get a character
  2843.     pop bx            ; Restore BX
  2844. ENDIF
  2845.     mov ah,al
  2846.     cmp parflg,parnon    ; Is the parity none?   [10]
  2847.     je inchr5        ; We're done.        [10]
  2848.     and ah,7FH                      ; Turn off the parity bit.
  2849. inchr5: jmp rskp
  2850.  
  2851. ; Set parity for character in Register AL.
  2852.  
  2853. dopar:    cmp parflg,parnon    ; No parity?            [10 start]
  2854.     je parret        ; Just return
  2855.     cmp parflg,parevn    ; Even parity?
  2856.     jne dopar0
  2857.     and al,07FH        ; Strip parity.
  2858.     jpe parret        ; Already even, leave it.
  2859.     or al,080H        ; Make it even parity.
  2860.     jmp parret
  2861. dopar0:    cmp parflg,parmrk    ; Mark parity?
  2862.     jne dopar1
  2863.     or al,080H        ; Turn on the parity bit.
  2864.     jmp parret
  2865. dopar1:    cmp parflg,parodd    ; Odd parity?    
  2866.     jne dopar2
  2867.     and al,07FH        ; Strip parity.
  2868.     jpo parret        ; Already odd, leave it.
  2869.     or al,080H        ; Make it odd parity.
  2870.     jmp parret
  2871. dopar2: and al,07FH        ; Space parity - turn off parity bit.
  2872. parret: ret                            ; [10 end]
  2873. PORT    ENDP
  2874.  
  2875. ; Clear the input buffer before sending a packet. [20e]
  2876. IF ibmpc
  2877. CLRBUF    PROC    NEAR
  2878.     lea ax,cs:source    ; Initialize the pointers
  2879.     mov cs:srcpnt,ax
  2880.     mov cs:savesi,ax
  2881.     mov cs:count,0
  2882.     mov di,cs:srcpnt    ; Where to store bytes
  2883.     mov ax,cs        ; Ready ES for string operations
  2884.     mov es,ax
  2885.     mov si,0        ; Where to fetch bytes
  2886.     ret
  2887. CLRBUF    ENDP
  2888. ENDIF
  2889.  
  2890. ; Receive_Packet
  2891. ; This routine waits for a packet arrive from the host.  It reads
  2892. ; chars until it finds a SOH.
  2893.  
  2894. RPACK    PROC    NEAR
  2895. IF ibmpc
  2896.     mov ah,2
  2897.     mov dx,scrst        ; Position cursor.
  2898.     mov bh,0
  2899.     int bios
  2900. ENDIF
  2901. IF Z100
  2902.     mov ah,prstr        ; Get the function to print string
  2903.     mov dx,offset scrst    ; Get the string address
  2904.     int dos            ; Position the cursor
  2905. ENDIF
  2906.     mov ah,prstr
  2907.     mov dx,offset infms0
  2908.         int dos
  2909. rpack5: call inpkt              ; Read up to a carriage return.
  2910.          jmp r                  ;  Return bad.
  2911. rpack0: call getchr             ; Get a character.
  2912.          jmp r                  ;  Hit the carriage return, return bad.
  2913.         cmp ah,soh              ; Is the char the start of header char?
  2914.          jne rpack0             ;  No, go until it is.
  2915. rpack1: call getchr             ; Get a character.
  2916.          jmp r                  ;  Hit the carriage return, return bad.
  2917.         cmp ah,soh              ; Is the char the start of header char?
  2918.          jz rpack1              ;  Yes, then go start over.
  2919.         mov cl,ah               ; Start the checksum.
  2920.         sub ah,' '+3            ; Get the real data count.
  2921.         mov dh,ah               ; Save it for later.
  2922.         mov al,ah               ; Swap halves.
  2923.         mov ah,0
  2924.         mov argbk1,ax           ; Save the data count.
  2925.         call getchr             ; Get a character.
  2926.          jmp r                  ;  Hit the carriage return, return bad.
  2927.         cmp ah,soh              ; Is the char the start of header char?
  2928.          jz rpack1              ;  Yes, then go start over.
  2929.         add cl,ah               ; Add it to the checksum.
  2930.         sub ah,' '              ; Get the real packet number.
  2931.         mov al,ah               ; Swap halves.
  2932.         mov ah,0
  2933.         mov argblk,ax           ; Save the packet number.
  2934.         call getchr             ; Get a character.
  2935.          jmp r                  ;  Hit the carriage return, return bad.
  2936.         cmp ah,soh              ; Is the char the start of header char?
  2937.          jz rpack1              ;  Yes, then go start over.
  2938.         mov temp,ax             ; Save the message type. [11]
  2939.         add cl,ah               ; Add it to the checksum.
  2940.         mov bx,offset data      ; Point to the data buffer.
  2941. rpack2: dec dh                  ; Any data characters?
  2942.          js rpack3              ;  If not go get the checksum.
  2943.         call getchr             ; Get a character.
  2944.          jmp r                  ;  Hit the carriage return, return bad.
  2945.         cmp ah,soh              ; Is the char the start of header char?
  2946.          jz rpack1              ;  Yes, then go start over.
  2947.         mov [bx],ah             ; Put the char into the packet.
  2948.         inc bx                  ; Point to the next character.
  2949.         add cl,ah               ; Add it to the checksum.
  2950.         jmp rpack2              ; Go get another.
  2951. rpack3: call getchr             ; Get a character.
  2952.          jmp r                  ;  Hit the carriage return, return bad.
  2953.         cmp ah,soh              ; Is the char the start of header char?
  2954.          jz rpack1              ;  Yes, then go start over.
  2955.         sub ah,' '              ; Turn the char back into a number.
  2956.         mov dh,cl               ; Get the character total.
  2957.         and dh,0C0H             ; Turn off all but the two high order bits.
  2958.     mov ch,cl
  2959.     mov cl,6
  2960.         shr dh,cl               ; Shift them into the low order position.
  2961.     mov cl,ch
  2962.         add dh,cl               ; Add it to the old bits.
  2963.         and dh,3FH              ; Turn off the two high order bits.  (MOD 64)
  2964.         cmp dh,ah               ; Are they equal?
  2965.          jz rpack4              ;  If so finish up.
  2966.         ret
  2967. rpack4: mov ah,0
  2968.         mov [bx],ah             ; Put a null at the end of the data.
  2969.         mov ax,temp             ; Get the type.   [11]
  2970.         jmp rskp
  2971. RPACK   ENDP
  2972.  
  2973.  
  2974. INPKT   PROC    NEAR
  2975.     mov bl,cxzflg        ; Remember original value. [20b]
  2976.     mov tmp,bl        ; Store it here. [20b]
  2977.         mov bx,offset recpkt    ; Point to the beginning of the packet.
  2978.     mov incnt,0
  2979. inpkt2: call inchr              ; Get a character.
  2980.          jmp inpkt0            ;  Return failure. [20b]
  2981.      nop            ;  Make it three bytes long. [20b] 
  2982.         mov [bx],ah             ; Put the char in the packet.
  2983.         inc bx
  2984.     inc incnt
  2985.         cmp ah,reol             ; Is it the EOL char?
  2986.         jne inpkt2              ; If not loop for another.
  2987.     cmp incnt,1        ; Ignore bare CR.   [2 start]
  2988.     jne inpkt6
  2989.     mov incnt,0
  2990.     mov bx,offset recpkt
  2991.     jmp inpkt2        ;                   [2 end]
  2992. inpkt6:    cmp ibmflg,0            ; Is this the (dumb) IBM mainframe?
  2993.         jz inpkt4               ; If not then proceed.
  2994. inpkt5: cmp state,'S'           ; Check if this is the Send-Init packet.
  2995.         jz inpkt4               ; If so don't wait for the XON.
  2996. inpkt3: call inchr              ; Wait for the turn around char.
  2997.          jmp inpkt0            ;  Return failure. [20b]
  2998.      nop            ;  Make it three bytes long.  [20b]
  2999.         cmp ah,xon              ; Is it the IBM turn around character?
  3000.         jne inpkt3              ; If not, go until it is.
  3001. inpkt4: mov bx,offset recpkt
  3002.         mov pktptr,bx           ; Save the packet pointer.
  3003.     mov bl,tmp        ; Get the original value. [20b]
  3004.     cmp bl,cxzflg        ; Did ^X/^Z flag change? [20b]
  3005.     je inpkx        ; If not, just return.  [20b]
  3006.     call intmsg         ; Else, say we saw the interrupt. [20b]
  3007. inpkx:  jmp rskp                ; If so we are done.
  3008. inpkt0:    mov bl,tmp        ; Get the original value. [20b]
  3009.     cmp bl,cxzflg        ; Did ^X/^Z flag change? [20b]
  3010.     je inpky        ; If not, just return failure.  [20b]
  3011.     call intmsg         ; Else, say we saw the interrupt. [20b]
  3012. inpky:    jmp r
  3013. INPKT   ENDP
  3014.  
  3015. GETCHR  PROC    NEAR
  3016.         push bx
  3017.         mov bx,pktptr           ; Get the packet pointer.
  3018.         mov ah,[bx]             ; Get the char.
  3019.         inc bx
  3020.         mov pktptr,bx
  3021.         pop bx                  ; Restore BX.
  3022.         cmp ah,reol             ; Is it the EOL char?
  3023.         jne getcr2              ; If not return retskp.
  3024.         ret                     ; If so return failure.
  3025. getcr2: jmp rskp
  3026. GETCHR  ENDP
  3027.  
  3028.  
  3029. ; This is where we go if we get an error packet.  A call to ERROR 
  3030. ; positions the cursor and prints the message.  A call to ERROR1
  3031. ; just prints a CRLF and then the message.  [8]
  3032.  
  3033. ERROR   PROC    NEAR
  3034.         mov state,'A'           ; Set the state to abort.
  3035.         call erpos            ; Position the cursor.
  3036.     jmp error2
  3037. error1:    mov ah,prstr
  3038.     mov dx,offset crlf
  3039.     int dos
  3040. error2: mov bx,argbk1           ; Get the length of the data.
  3041.         add bx,offset data      ; Get to the end of the string.
  3042.         mov ah,'$'              ; Put a dollar sign at the end.
  3043.         mov [bx],ah
  3044.         mov ah,prstr            ; Print the error message.
  3045.         mov dx,offset data
  3046.         int dos
  3047.         ret
  3048. ERROR   ENDP
  3049.  
  3050. ; LOGOUT - tell remote KERSRV to logout.
  3051.  
  3052. LOGOUT    PROC    NEAR                        ; [8 start]
  3053.     mov ah,cmcfm
  3054.     call comnd        ; Get a confirm.
  3055.      jmp r
  3056.     call logo
  3057.      jmp rskp        ; Go get another command whether we ....
  3058.     jmp rskp        ; .... succeed or fail.
  3059. LOGOUT    ENDP
  3060.  
  3061. LOGO    PROC    NEAR
  3062.     mov numtry,0        ; Initialize count.
  3063.     call serini        ; Initialize port.  [14]
  3064. logo1:    mov ah,numtry
  3065.     cmp ah,maxtry        ; Too many times?
  3066.     js logo3        ; No, try it.
  3067. logo2:    mov ah,prstr
  3068.     mov dx,offset erms19
  3069.     int dos
  3070.     call serrst        ; Reset port.  [14]
  3071.     ret
  3072. logo3:    inc numtry        ; Increment number of tries.
  3073.     mov argblk,0        ; Packet number zero.
  3074.     mov argbk1,1        ; One piece of data.
  3075.     mov bx,offset data
  3076.     mov ah,'L'
  3077.     mov [bx],ah        ; Logout the remote host.
  3078.     mov ah,'G'        ; Generic command packet.
  3079.     call spack
  3080.      jmp logo2        ; Tell user and die.
  3081.      nop
  3082.     call rpack5        ; Get ACK (w/o screen msgs.)
  3083.      jmp logo1        ; Go try again.
  3084.      nop
  3085.     cmp ah,'Y'        ; ACK?
  3086.     jne logo4
  3087.     call serrst        ; Reset port.  [14]
  3088.     jmp rskp
  3089. logo4:    cmp ah,'E'        ; Error packet?    
  3090.     jnz logo1        ; Try sending the packet again.
  3091.     call error1
  3092.     call serrst        ; Reset port.  [14]
  3093.     ret
  3094. LOGO    ENDP
  3095.  
  3096. ; FINISH - tell remote KERSRV to exit.
  3097.  
  3098. FINISH    PROC    NEAR
  3099.     mov ah,cmcfm        ; Parse a confirm.
  3100.     call comnd
  3101.      jmp r
  3102.     mov numtry,0        ; Initialize count.
  3103.     call serini        ; Initialize port.  [14]
  3104. fin1:    mov ah,numtry
  3105.     cmp ah,maxtry        ; Too many times?
  3106.     js fin3            ; Nope, try it.
  3107. fin2:    mov ah,prstr
  3108.     mov dx,offset erms18
  3109.     int dos
  3110.     call serrst        ; Reset port.  [14]
  3111.     jmp rskp        ; Go home.
  3112. fin3:    inc numtry        ; Increment number of tries.
  3113.     mov argblk,0        ; Packet number zero.
  3114.     mov argbk1,1        ; One piece of data.
  3115.     mov bx,offset data
  3116.     mov ah,'F'
  3117.     mov [bx],ah        ; Finish running Kermit.
  3118.     mov ah,'G'        ; Generic command packet.
  3119.     call spack
  3120.      jmp fin2        ; Tell user and die.
  3121.      nop
  3122.     call rpack5        ; Get ACK (w/o screen stuff).
  3123.      jmp fin1        ; Go try again.
  3124.      nop
  3125.     cmp ah,'Y'        ; Got an ACK?
  3126.     jnz fin4
  3127.     call serrst        ; Reset port. [14]
  3128.     jmp rskp        ; Yes, then we're done.
  3129. fin4:    cmp ah,'E'        ; Error packet?
  3130.     jnz fin1        ; Try sending it again.
  3131.     call error1
  3132.     call serrst        ; Reset port.  [14]
  3133.     jmp rskp
  3134. FINISH    ENDP
  3135.  
  3136. ; BYE command - tell remote KERSRV to logout & exits to DOS.  
  3137.  
  3138. BYE    PROC    NEAR
  3139.     mov ah,cmcfm        ; Parse a confirm.
  3140.     call comnd
  3141.      jmp r
  3142.     call logo        ; Tell the mainframe to logout.
  3143.       jmp rskp        ; Failed - don't exit.
  3144.     mov extflg,1        ; Set exit flag.
  3145.     jmp rskp                    ; [8 end]
  3146. BYE    ENDP
  3147.  
  3148. ; This is the 'exit' command.  It leaves KERMIT and returns to DOS.
  3149.  
  3150. EXIT    PROC    NEAR
  3151.         mov ah,cmcfm
  3152.         call comnd              ; Get a confirm.
  3153.          jmp r
  3154.         mov extflg,1            ;  Set the exit flag.
  3155.         jmp rskp                ; Then return to system.
  3156. EXIT    ENDP
  3157.  
  3158.  
  3159. ; This is the 'help' command.  It gives a list of the commands.
  3160.  
  3161. HELP    PROC    NEAR
  3162.         mov ah,cmcfm
  3163.         call comnd              ; Get a confirm.
  3164.          jmp r
  3165.         mov ah,prstr            ; Print a string to the console.
  3166.         mov dx,offset tophlp    ; The address of the help message.
  3167.         int dos
  3168.         jmp rskp
  3169. HELP    ENDP
  3170.  
  3171. IF ibmpc
  3172. source    db    2048 DUP(?)    ; Buffer for data from port.
  3173. srcpnt    dw    0        ; Pointer in buffer (DI).
  3174. count    dw    0        ; Number of chars in int buffer.
  3175. savesi    dw    0        ; Save SI register here.    
  3176. telflg    db    0        ; Are we acting as a terminal. [16] [17c]
  3177. mst    dw    0        ; Modem status address. [19b]
  3178. mdat    dw    0        ; Modem data address. [19b]
  3179. mdeoi    db    0        ; End-of-Interrupt value. [19b]
  3180. ENDIF
  3181.  
  3182. ;       This is the CONNECT command.
  3183.  
  3184. TELNET  PROC    NEAR
  3185.         mov ah,cmcfm
  3186.         call comnd              ; Get a confirm.
  3187.          jmp r                  ;  Didn't get a confirm.
  3188.         mov ah,prstr            ; Output
  3189.         mov dx,offset crlf      ; a crlf.
  3190.         int dos
  3191.     call dobaud        ; Set baud rate. [19a]
  3192.     call domsg        ; Reassure user. [19b]
  3193. IF ibmpc
  3194.     mov ah,3        ; Get cursor position.  [17b start, 20g]
  3195.     mov bh,0
  3196.     int bios
  3197.     cmp dh,24        ; Are we on row 25? [19d]
  3198.     jne nobump        ; Nope, then leave where it is. [19d]
  3199.     dec dh            ; Decrement ROW attribute. (DT)
  3200.     mov ah,2
  3201.     int bios        ; [17b end]
  3202. nobump:    mov cs:telflg,0FFH    ; Turn on Telnet flag.  [16] [17c] [20g]
  3203.     call serini        ; Initialize serial port. [14]
  3204.     xor ax,ax
  3205.     mov cx,ds        ; Save DS in CX.
  3206.     mov ds,ax        ; Use low core.
  3207.     mov bx,6CH        ; "break" interrupt vector.
  3208.     push [bx]
  3209.     mov bx,6EH
  3210.     push [bx]
  3211.     mov bx,6CH
  3212.     mov ax,offset intret
  3213.     mov es,ax
  3214.     mov [bx],es        ; ignore break int's (pt to "iret").
  3215.     mov bx,6EH
  3216.     mov [bx],cs
  3217.     mov ds,cx
  3218.     mov ssp,sp        ; Save SP to make an easy return.
  3219. ENDIF
  3220. IF Z100
  3221.     mov ssp,sp        ; Save current stack pointer.
  3222. ENDIF
  3223. telnoe: call plup        ; Char at port (type to console) ?
  3224. IF ibmpc
  3225.     cmp al,ESC
  3226.     jne telx
  3227.     jmp telesc
  3228. ENDIF
  3229. telx:    cmp al,DEL        ; Don't bother with deletes.
  3230.     je telnoe
  3231.     cmp al,XOFF        ; Skip all the following too.
  3232.     je telnoe
  3233.     cmp al,XON    
  3234.     je telnoe
  3235.     cmp al,00H        ; Null.
  3236.     je telnoe
  3237. IF ibmpc
  3238.     cmp al,BELL
  3239.     jne nobell
  3240.     call beep
  3241.     jmp telnoe
  3242. nobell:    cmp al,TAB        ; Tab ? [15]
  3243.     jne notab        ; No, skip the jump [15]
  3244.     call dotab        ; Yes, handle the tab [15]
  3245.     jmp telnoe        ; And get the next character [15]
  3246. notab:    call dotty        ; Use our own TTY I/O.  [17b]
  3247.     jmp telnoe
  3248. ENDIF
  3249. IF Z100
  3250.     mov dl,al        ; Get the character
  3251.     mov ah,dconio        ; and the function
  3252.     int dos            ; type the character
  3253.     jmp telnoe        ; Get next character
  3254. ENDIF
  3255. TELNET  ENDP
  3256.  
  3257. ; Reassure user about connection to the host.  Tell him what escape
  3258. ; sequence to use to return and the communications port and baud
  3259. ; rate being used.   [19b] 
  3260.  
  3261. DOMSG    PROC    NEAR
  3262.     mov ah,prstr
  3263.     mov dx,offset tmsg1
  3264.     int dos
  3265.     call escprt
  3266.     mov ah,prstr
  3267.     mov dx,offset tmsg3
  3268.     int dos
  3269.     call baudprt        ; Say what baud rate we're using. [19a]
  3270. IF ibmpc
  3271.     mov ah,prstr
  3272.     mov dx,offset tmsg4
  3273.     int dos
  3274.     mov tmp,'1'        ; Assume COM1.
  3275.     cmp comflg,1
  3276.     je domsg0
  3277.     mov tmp,'2'        ; Nope, we're using COM2.
  3278. domsg0:    mov dx,offset tmp
  3279.     int dos
  3280. ENDIF
  3281.     mov ah,prstr
  3282.     mov tmp,']'
  3283.     mov dx,offset tmp
  3284.     int dos
  3285.     mov dx,offset crlf    ; Output 3 CRLF's.
  3286.     int dos
  3287.     int dos
  3288.     int dos
  3289.     ret
  3290. DOMSG    ENDP
  3291.  
  3292. ; Put character in AL to the screen.  [17b start]
  3293. IF ibmpc 
  3294. DOTTY    PROC NEAR
  3295.     push ax
  3296.     mov ah,3        ;Get cursor
  3297.     mov bh,0
  3298.     int bios
  3299.     pop ax
  3300.     cmp al,8        ;Backspace?
  3301.     je dotty3
  3302.     cmp al,0DH        ;CR?
  3303.     je dotty4
  3304.     cmp al,0AH        ;LF?
  3305.     je dotty5
  3306.     cmp incmod,0        ;I/C?
  3307.     jne dotty7
  3308.     mov ah,9        ;Ordinary character
  3309.     mov bx,curatt
  3310.     mov cx,1
  3311.     int bios
  3312.     mov ah,2
  3313.     mov bh,0
  3314.     inc dl            ;Step cursor
  3315.     cmp dl,80        ;Overflow?
  3316.     jne dotty2
  3317.     ret
  3318. dotty1:    inc dh
  3319. dotty6:    mov ah,2
  3320. dotty2:    int bios
  3321.     ret
  3322. dotty3:    dec dl            ;BS
  3323.     jge dotty6
  3324.     ret
  3325. dotty4:    mov dl,0        ;CR
  3326.     jmp dotty6
  3327. dotty5:    cmp dh,23        ;LF
  3328.     jl dotty1
  3329.     mov ah,8        ;Get attribute of last line
  3330.     int bios
  3331.     mov bh,ah
  3332.     mov ax,0601H        ;Scroll
  3333.     sub cx,cx
  3334.     mov dx,174FH
  3335.     jmp dotty2
  3336. dotty7:    mov temp,ax        ;DK6 Save the character
  3337.     mov temp1,dx        ;Save the cursor
  3338.     mov dl,78        ;Start shift at end of line
  3339.     mov temp2,dx
  3340.     mov ah,1        ;Turn off cursor
  3341.     mov ch,20H
  3342.     int bios
  3343. dotty8:    mov ah,2        ;Position to col M
  3344.     mov bh,0
  3345.     mov dx,temp2
  3346.     int bios
  3347.     mov ah,8        ;Read char/attr
  3348.     int bios
  3349.     mov cx,ax        ;Save it
  3350.     mov ah,2        ;Position to col M+1
  3351.     inc dx
  3352.     int bios
  3353.     mov ah,9        ;Write char/attr
  3354.     mov al,cl
  3355.     mov bl,ch
  3356.     mov cx,1
  3357.     int bios
  3358.     dec dx
  3359.     dec temp2
  3360.     cmp dx,temp1
  3361.     jne dotty8
  3362.     mov ah,2        ;Position
  3363.     mov bh,0
  3364.     int bios
  3365.     mov ax,temp        ;Write the char
  3366.     mov ah,9
  3367.     mov bx,curatt        ;In the current video mode
  3368.     mov cx,1
  3369.     int bios
  3370.     mov ah,2        ;Step to next column
  3371.     inc dl
  3372.     int bios
  3373.     mov ah,1        ;Turn on cursor
  3374.     mov cx,0B0CH
  3375.     int bios
  3376.     ret            ; [17b end]
  3377. DOTTY    ENDP
  3378. ENDIF
  3379.  
  3380. EXTLN    PROC    NEAR
  3381. IF ibmpc
  3382.     call serrst        ; Reset serial port. [14]
  3383.     mov sp,ssp
  3384.     xor bx,bx
  3385.     mov cx,ds        ; Save DS register.
  3386.     mov ds,bx        ; Address low memory.
  3387.     mov bx,6EH
  3388.     pop [bx]
  3389.     mov bx,6CH
  3390.     pop [bx]
  3391. ;    mov bx,mdmintv+2        ; Restore old interrupt vectors.
  3392. ;    pop [bx]
  3393. ;    mov bx,mdmintv
  3394. ;    pop [bx]
  3395.     mov ds,cx        ; Restore DS.
  3396.     xor bx,bx
  3397.     mov cs:telflg,0      ; Not acting as terminal anymore. [16] [17c] [20g]
  3398. ;    sti
  3399. ENDIF
  3400. IF Z100
  3401.     mov sp,ssp    
  3402. ENDIF
  3403.     mov ah,prstr
  3404.     mov dx,offset tmsg2
  3405.     int dos
  3406.     jmp rskp
  3407. EXTLN    ENDP
  3408.  
  3409. ;[14 start]       Common initialization for using serial port.
  3410.  
  3411. SERINI    PROC    NEAR
  3412. IF ibmpc
  3413.     cli            ; Disable interrupts
  3414.     cld            ; Do increments in string operations
  3415.     xor ax,ax        ; Address low memory
  3416.     mov es,ax
  3417.     mov bx,mdintv        ; Save serial card interrupt vector. [19b]
  3418.     mov ax,es:[bx]
  3419.     mov savsci,ax
  3420.     mov ax,offset serint    ; And point it to my routine
  3421.     mov es:[bx],ax
  3422.     add bx,2        ; Save CS register too. [19b]
  3423.     mov ax,es:[bx]
  3424.     mov savscs,ax
  3425.     mov es:[bx],cs
  3426.     call clrbuf        ; Clear input buffer. [20e]
  3427.     mov ax,mdstat        ; [19b]
  3428.     mov cs:mst,ax        ; Use this address for status. [19b]
  3429.     mov ax,mddat        ; [19b]
  3430.     mov cs:mdat,ax        ; Use this address for data. [19b]
  3431.     mov al,mdmeoi        ; [19b]
  3432.     mov cs:mdeoi,al        ; Use to signify end-of-interrupt. [19b]
  3433.     in al,21H        ; Set up 8259 interrupt controller
  3434.     and al,mden        ; Enable INT3 or INT4. [19b]
  3435.     out 21H,al
  3436.     mov dx,mdcom        ; Set up the serial card. [19b]
  3437.     mov al,3
  3438.     out dx,al
  3439.     mov dl,0F9H        ; [19b]
  3440.     mov al,1        ; Set up interrupt enable register
  3441.     out dx,al
  3442.     mov dl,0FCH        ; Enable interrupts from serial card
  3443.     mov al,0BH
  3444.     out dx,al
  3445.     sti            ; Allow interrupts
  3446.     mov dl,0F8H
  3447.     in al,dx
  3448. ENDIF
  3449.     ret
  3450. SERINI    ENDP
  3451.  
  3452. SERRST    PROC    NEAR
  3453. IF ibmpc
  3454.     cli            ; Disable interrupts
  3455.     mov dx,03FCH        ; Disable modem interrupts
  3456.     cmp comflg,1        ; Using port 1 ? [19b]
  3457.     je srst0        ; Yes - continue. [19b]
  3458.     mov dh,02        ; Set for port 2. [19b]
  3459. srst0:    mov al,3        ; [new label - 19b]
  3460.     out dx,al
  3461.     in al,21H        ; Interrupt controller
  3462.     or al,mddis        ; Inhibit IRQ3 or IRQ4. [19b]
  3463.     out 21H,al
  3464.     xor bx,bx        ; Address low memory
  3465.     mov es,bx
  3466.     mov bx,mdintv        ; Restore the serial card int vector [19b]
  3467.     mov ax,savsci
  3468.     mov es:[bx],ax
  3469.     add bx,2        ; Restore CS too. [19b]
  3470.     mov ax,savscs
  3471.     mov es:[bx],ax
  3472.     sti
  3473. ENDIF
  3474.     ret
  3475. SERRST    ENDP                    ; [14 end]
  3476.  
  3477. ; *********** serial port interrupt routine ********
  3478.  
  3479. IF ibmpc
  3480. SERINT  PROC  NEAR
  3481.     push dx
  3482.     push ax
  3483.     push es
  3484.     push di
  3485.     cld
  3486.     mov di,cs:srcpnt    ; Registers for storing data.
  3487.     mov ax,cs
  3488.     mov es,ax
  3489.     mov dx,cs:mst        ; Asynch status port. [19b]
  3490.     in al,dx
  3491.     test al,mdminp        ; Data available?
  3492.     jz retint        ; Nope.
  3493.     mov dx,cs:mdat        ; [19b]
  3494.     in al,dx
  3495.     mov ah,0FFH        ; Assume X-fer mode. [16 start]
  3496.     cmp cs:telflg,0        ; File transfer or terminal mode? [17c]
  3497.     jz srint0
  3498.     mov ah,7FH        ; Terminal mode (7 bits only). 
  3499. srint0:    and al,ah        ; Fiddle with input. [16 end]
  3500.     jz retint        ; Ignore nulls.
  3501.     cmp al,7FH        ; Ignore rubouts, too.
  3502.     jz retint
  3503.     stosb            ; Store char in buffer.
  3504.     lea ax,cs:source
  3505.     sub di,ax
  3506.     and di,7FFH        ; Truncate buffer here.
  3507.     add di,ax
  3508.     inc cs:count
  3509. retint:    mov cs:srcpnt,di
  3510.     sti
  3511.     mov al,mdeoi        ; [19b]
  3512.     out intcon1,al        ; Send End-of-Interrupt to 8259.
  3513.     pop di
  3514.     pop es
  3515.     pop ax
  3516.     pop dx
  3517. intret:    iret
  3518. SERINT    ENDP
  3519. ENDIF
  3520.  
  3521. PLUP    PROC    NEAR
  3522.     call conchr        ; Check keyboard.   [15 begin]
  3523.      jmp extln        ; Exit from Telnet
  3524.      nop            ; In case it is a short jump (Z100)
  3525.     call prtchr        ; Check serial port
  3526.      ret            ; Got a character
  3527.      nop            ; Use up three bytes.  [15 end] 
  3528.      nop
  3529.     jmp plup
  3530. PLUP    ENDP
  3531.  
  3532. ;************************System Dependent****************************
  3533.  
  3534. ; These I/O routines are similar to those just above.
  3535.  
  3536. PRTCHR  PROC    NEAR
  3537. IF ibmpc
  3538.     cmp cs:count,0
  3539.     jnz prtch2
  3540.     jmp rskp        ; No data - check console.
  3541. prtch2: cli            ; Disable int's.
  3542.     mov cx,ds
  3543.     mov ax,cs
  3544.     mov ds,ax
  3545.     mov si,cs:savesi
  3546.     lodsb            ; Get char from buffer.
  3547.     lea dx,cs:source
  3548.     sub si,dx
  3549.     and si,7FFH        ; Truncate buffer after here.
  3550.     add si,dx
  3551.     dec cs:count
  3552.     mov cs:savesi,si 
  3553.     mov ds,cx
  3554.     sti            ; Renable int's.
  3555.     ret
  3556. ENDIF
  3557. IF Z100
  3558.     push bx            ; Save BX
  3559.     mov ah,chr_status    ; Get the function we want
  3560.     mov al,chr_sfgs        ; Get the subfunction to get status
  3561.     call bios_auxfunc    ; Perform the function
  3562.     cmp bl,0        ; Anything in queue?
  3563.     jne prtch1        ; Yes, go get it
  3564.     pop bx            ; Restore BX
  3565.     jmp rskp        ; No, give skip return
  3566. prtch1:    mov ah,chr_read        ; Want to read character
  3567.     call bios_auxfunc    ; Do it
  3568.     and al,07FH        ; Strip off parity bit
  3569.     pop bx            ; And restore BX
  3570.     ret
  3571. ENDIF
  3572. PRTCHR  ENDP
  3573.  
  3574.  
  3575. ; Generate a short beep.
  3576.  
  3577. IF ibmpc
  3578. BEEP    PROC    NEAR
  3579.     mov al,10110110B    ; Gen a short beep (long one losses data.)
  3580.     out timer+3,al        ; Code snarfed from Technical Reference.
  3581.     mov ax,533H
  3582.     out timer+2,al
  3583.     mov al,ah
  3584.     out timer+2,al
  3585.     in al,port_b
  3586.     mov ah,al
  3587.     or al,03
  3588.     out port_b,al
  3589.     sub cx,cx
  3590.     mov bl,1
  3591. beep0:  loop beep0
  3592.     dec bl        
  3593.     jnz beep0
  3594.     mov al,ah
  3595.     out port_b,al
  3596.     ret
  3597. BEEP    ENDP 
  3598. ENDIF
  3599.  
  3600. CONCHR  PROC    NEAR
  3601. IF ibmpc
  3602.     mov ah,1        ; Get keyboard status.
  3603.     int keyb
  3604.     jnz cnc0x    
  3605.     jmp rskp
  3606. cnc0x:    mov ah,0        ; Read a char.
  3607.     int keyb
  3608.     cmp al,0        ; Special char (cntrl-break)?
  3609.     jnz nobrk        ; Nope.
  3610.     cmp ah,3        ; 3 in ah means nul code.
  3611.     jz nobrk        ; Pass nulls.  [14]
  3612.     cmp ah,83        ; Del Key?  [14]
  3613.     je cnc1r        ; Yes - send a rubout. [14]
  3614.     cmp ah,0        ; Cntrl-Break?
  3615.     jne cnc1y
  3616.     call sendbr        ; Send a break. [20g]
  3617. cnc1y:    jmp rskp    
  3618. ENDIF
  3619. IF Z100
  3620.     mov ah,dconio        ; Determine if character present
  3621.     mov dl,0ffH        ; Want input
  3622.     int dos            ; Get status
  3623.     cmp al,00H        ; Any characters there?
  3624.     jne nobrk        ; if not, forget it
  3625.     jmp rskp        ; Give skip return
  3626. ENDIF
  3627.  
  3628. cnc1r:    cmp delflg,0        ; Translate BS to DEL? [19c]
  3629.     je dobs            ; Nope, BS=BS [19c]    
  3630.     mov al,BS        ; BS (will be converted to DEL) [15]
  3631.     jmp nobrk
  3632. dobs:    mov al,07FH        ; ASCII rubout.  [14]
  3633. nobrk:  mov dl,al        ; Store char here.
  3634.     mov ah,escchr           ; Get the escape char.
  3635.         cmp ah,dl               ; Is it an escape char?
  3636.         jz intchr               ; If so go process it.
  3637.     cmp delflg,0        ; Translate BS to DEL?  [19c]
  3638.     je dobs1        ; Nope, BS=BS  [19c]
  3639.     cmp dl,BS        ; Is it a backspace ? [15 begin]
  3640.     jnz cch0        ; No, check for delete
  3641.     mov dl,DEL        ; Yes, get a delete
  3642.     jmp cch1        ; And send that instead
  3643. cch0:    cmp dl,DEL        ; Is it a delete ?
  3644.     jnz cch1        ; No, done checking then
  3645.     mov dl,BS        ; Yes, use a backspace
  3646. cch1:    mov ax,dx        ; Copy character back to AX  [15 end]
  3647. dobs1:    call dopar        ; Set parity (if any).   [10]
  3648.     mov dx,ax
  3649.     push dx
  3650.         call prtout             ; Output the char to the port.
  3651.     pop dx
  3652.         mov ah,ecoflg           ; Get the echo flag.
  3653.         cmp ah,0                        ; Is it turned on?
  3654.     jnz cnc1x
  3655.         jmp rskp                 ; If not we're done here.
  3656. cnc1x:  and dl,7FH
  3657.     cmp dl,BS        ; Backspace?
  3658.     je cnc2x
  3659.     cmp dl,CR        ; Carriage return?
  3660.     je cnc2x
  3661. IF ibmpc
  3662.     cmp dl,BELL
  3663.     jne cnc2y
  3664.     call beep
  3665.     jmp rskp
  3666. ENDIF
  3667. cnc2y:    cmp dl,20H        ; Is it a control char?
  3668.     jge cnc2x    
  3669.     jmp rskp
  3670. cnc2x:    mov ah,dconio           ; Direct console output.
  3671.         int dos                 ; Echo the char.
  3672.         jmp rskp
  3673. CONCHR  ENDP
  3674.  
  3675. ; One routine to send a break for the IBM-PC and Z100. [20g]
  3676. SENDBR    PROC    NEAR
  3677.     push cx
  3678.     push dx
  3679.     push ax
  3680.     xor cx,cx        ; Clear loop counter.
  3681.     mov dx,mdcom        ; Port address.  [19b]
  3682.     in al,dx        ; Get current setting.
  3683.     or al,BRKBIT        ; Set send-break bit(s).
  3684.     out dx,al        ; Start the break.
  3685. pause:    loop pause        ; Wait a while.
  3686.     xor al,BRKBIT        ; Clear send-break bit(s).
  3687.     out dx,al        ; Stop the break.
  3688.     pop ax
  3689.     pop dx
  3690.     pop cx
  3691.     ret            ; And return.
  3692. SENDBR    ENDP
  3693.  
  3694. CONN    PROC    NEAR     
  3695. intchr: mov ah,dconio           ; Direct console I/O.
  3696.         mov dl,0FFH             ; Input.
  3697.         int dos                 ; Get a char.
  3698.     mov ah,al
  3699.     cmp ah,0                        ; Is the char a null?
  3700.         jz intchr               ; If so, go until we get a char.
  3701.         mov bh,ah               ; Save the actual char.
  3702.         and ah,137O             ; Convert to upper case.
  3703.         cmp ah,'C'                      ; Is it close?
  3704.         jne intch0
  3705.         ret
  3706. intch0: cmp ah,'S'                      ; Is it status?
  3707.     jnz inc0x
  3708.         jmp stat01              ; If so, jump to stat01 (it will return).
  3709. inc0x:  cmp ah,'B'        ; Send a break? [20g]
  3710.     jne inc1x        ; No. [20g]
  3711.     call sendbr        ; Yes, so send a break. [20g]
  3712.     jmp rskp        ; And return.  [20g]
  3713. inc1x:    mov ah,bh                       ; Get the char.
  3714.         cmp ah,'?'                      ; Is it help?
  3715.         jne intch1              ; If not, go to the next check.
  3716.         mov dx,offset inthlp    ; If so, get the address of the help message.
  3717.         mov ah,prstr            ; Print it.
  3718.         int dos
  3719.         jmp intchr              ; Get another char.
  3720. intch1: mov ch,ah               ; Put the char into another reg.
  3721.         mov ah,escchr           ; Get the escape char.
  3722.         cmp ah,ch               ; Is it the escape char?
  3723.         jne intch2              ; If not, go send a beep to the user.
  3724.     mov al,ch
  3725.     call dopar        ; Set parity.     [10] 
  3726. intc11: mov dl,al
  3727.     call prtout             ; Output it.
  3728.         jmp rskp                ; Return, we are done here.
  3729. intch2: mov dl,'G'-100O         ; Otherwise send a beep.
  3730.         mov ah,dconio
  3731.         int dos
  3732.         jmp rskp
  3733.  
  3734. ; Another similar I/O routine.
  3735.  
  3736. ;************************System Dependent****************************
  3737.  
  3738. prtout: mov al,dl               ; Char must be in al.
  3739. IF ibmpc
  3740.     mov dx,mddat        ; [19b]
  3741.     out dx,al
  3742. ENDIF
  3743. IF Z100
  3744.     call bios_auxout    ; Send the character
  3745. ENDIF
  3746.         ret
  3747. CONN    ENDP
  3748.  
  3749. ; [15 begin]
  3750. IF ibmpc            ; Only for IBM-PC's. [20g]
  3751. DOTAB    PROC NEAR
  3752.     mov ah,3        ; Read current cursor position.
  3753.     mov bh,0        ; This screen
  3754.     int bios        ; From bios
  3755.     cmp dl,72        ; Are we at the last tab stop ?
  3756.     jl dotab0        ; No, move to the next
  3757.     cmp dl,79        ; Are we at the end ?
  3758.     je dotab2        ; Yes, just return
  3759.     add dl,1        ; No, move forward one position
  3760.     jmp dotab1        ; Set the cursor position
  3761. dotab0:    mov al,dl        ; Get the column into al
  3762.     push dx            ; Save the current cursor position
  3763.     xor ah,ah        ; Zero the high end of ax
  3764.     mov bl,8        ; Get an eight
  3765.     xor bh,bh        ; Zero high byte
  3766.     div bl            ; Divide by 8
  3767.     mov al,ah        ; Put the remainder in the low end
  3768.     xor ah,ah        ; Zero the high end
  3769.     mov cl,8        ; Get an 8 into cl
  3770.     xor ch,ch        ; Zero high byte
  3771.     sub cl,al        ; Subtract al from cl
  3772.     xor ch,ch        ; Zero high end
  3773.     pop dx            ; Restore the current cursor position
  3774.     add dl,cl        ; And subtract column mod 8
  3775. dotab1:    mov ah,2        ; Set cursor position
  3776.     mov bh,0        ; This screen
  3777.     int bios        ; Bios call
  3778. dotab2:    ret            ; Return
  3779. DOTAB    ENDP
  3780. ENDIF                ; [20g]
  3781. ; [15 end]
  3782.  
  3783.  
  3784. IF ibmpc            ; [20g]
  3785. TELESC    PROC    NEAR
  3786.     cmp vtflg,0        ; Is vt52 flag on?
  3787.     jne vt0
  3788.     jmp telnoe        ; Don't do escape stuff if it's off.
  3789. vt0:    call plup
  3790.         mov ah,al                       ; Get the char.
  3791.     cmp ah,'Z'        ; Tell host our terminal type. [20a]
  3792.     je vtiden        ; [20a]
  3793.     cmp ah,'Y'        ; Special char - move cursor.
  3794.     jne vt1
  3795.     jmp movcur
  3796. vt1:    cmp ah,'<'        ; Start-ANSI?  [17b start] 
  3797.     je vtexit        ; Yes, ignore
  3798.     cmp ah,'['        ; An ANSI command?
  3799.     je vtansi        ; Yes, do it
  3800.     cmp ah,'@'        ; Insert characters?
  3801.     jne vtnins
  3802.     mov incmod,1
  3803.     jmp telnoe
  3804. vtnins:    cmp ah,'p'        ; Inverse?
  3805.     jne vtninv
  3806.     jmp vtinvi
  3807. vtninv:    cmp ah,'q'        ; Normal?
  3808.     jne vtnino
  3809.     jmp vtinvo        ; [17b end]
  3810. vtnino:    cmp ah,'A'        ; Less than an 'A'?
  3811.         jl vtig                 ; Yes - ignore.
  3812.         cmp ah,'O'+1            ; Greater than 'O'?   [17b]
  3813.         jns vtig                ; Yes - ignore.
  3814.         mov al,'A'
  3815.         sub ah,al               ; Else make into index.
  3816.         shl ah,1
  3817.         mov bx,offset ttab      ; Load base addr of table.
  3818.     mov cl,ah               ; Move a into cx.
  3819.         mov ch,00H              ; Zero out high byte.
  3820.         add bx,cx               ; Double add index+offset.
  3821.     mov bx,[bx]        ; Get address of routine to call.
  3822.     jmp bx
  3823. vtig:                           ; Ignore escape sequence.
  3824.         push ax                 ; Push the char to be output.
  3825.         mov dl,esc              ; Load an escape.
  3826.         mov ah,conout           ; The function code
  3827.         int dos                 ; and the syscal.
  3828.         pop ax                  ; Restore the character
  3829.         mov dl,ah               ; and move to output register.
  3830.         mov ah,conout           ; The function
  3831.         int dos                 ; and the syscall.
  3832. ENDIF
  3833. vtexit:    jmp telnoe        ; Return home. [17b]
  3834.  
  3835. ; Used for terminal-type querying programs.  [20a]
  3836. IF ibmpc
  3837. vtiden:    mov ah,ESC        ; Respond with "ESC / K".
  3838.     call outchr
  3839.      jmp telnoe        ; If failed, just forget the rest.
  3840.     mov ah,"/"
  3841.     call outchr
  3842.      jmp telnoe
  3843.     mov ah,"K"
  3844.     call outchr
  3845.      jmp telnoe        ; And return even if failed.
  3846.     jmp telnoe
  3847. ENDIF
  3848.  
  3849. ; ANSI Insert/Delete Line.  [17b start, 20g] 
  3850. IF ibmpc
  3851. vtansi:    call plup
  3852.     cmp al,'?'
  3853.     je vtanso
  3854.     sub al,30H
  3855.     mov temp,ax
  3856.     call plup
  3857.     cmp al,"9"
  3858.     jg vtans1
  3859.     sub al,30H
  3860.     mov temp2,ax
  3861.     mov ax,temp
  3862.     mov dl,10
  3863.     mul dl
  3864.     add ax,temp2
  3865.     mov temp,ax
  3866.     call plup
  3867. vtans1:    cmp al,'L'
  3868.     jne vtans2
  3869.     mov ah,3        ; Get cursor position
  3870.     mov bh,0
  3871.     int bios
  3872.     mov temp1,dx
  3873.     mov cx,dx        ; Do a N-line scroll
  3874.     mov cl,0
  3875.     mov dx,184FH
  3876.     mov ax,temp
  3877.     mov ah,7
  3878.     mov bh,7
  3879.     int bios
  3880.     jmp vtans3
  3881. vtans2: cmp al,'M'
  3882.     jne vtans4
  3883.     mov ah,3
  3884.     mov bh,0
  3885.     int bios
  3886.     mov temp1,dx
  3887.     mov ax,temp
  3888.     mov ah,6
  3889.     mov cx,dx
  3890.     mov dx,184FH
  3891.     mov bh,7
  3892.     int bios
  3893. vtans3: mov dx,temp1        ; Restore cursor position
  3894.     mov dl,0
  3895.     mov ah,2
  3896.     mov bh,0
  3897.     int bios
  3898. vtans4:    jmp telnoe
  3899. vtanso: call plup
  3900.     call plup
  3901.     jmp telnoe
  3902.  
  3903. vtinvi: mov curatt,0070H    ; Reverse video
  3904.     jmp telnoe
  3905. vtinvo: mov curatt,0007H    ; Normal video
  3906.     jmp telnoe        ;  [17b end]
  3907. TELESC    ENDP
  3908. ENDIF
  3909.  
  3910. IF ibmpc
  3911. TEL    PROC    NEAR
  3912. movcur:    call plup
  3913.     sub al,32
  3914.     mov dh,al
  3915.     mov temp,dx        ; Save row position here.
  3916.     call plup
  3917.     mov dx,temp        ; Restore
  3918.     sub al,32        ; Comes with 37Q added on (& starts at 1).
  3919.     mov dl,al
  3920.     mov bh,0
  3921.     mov ah,2
  3922.     int bios
  3923.     jmp telnoe
  3924.  
  3925. curup:    mov ah,3        ; Cursor up function.
  3926.     mov bh,0
  3927.     int bios
  3928.     cmp dh,0
  3929.     je cup0
  3930.     sub dh,1
  3931.     mov ah,2
  3932.     int bios
  3933. cup0:    jmp telnoe
  3934.  
  3935. curdwn:    mov ah,3        ; Cursor down.
  3936.     mov bh,0
  3937.     int bios
  3938.     cmp dh,24
  3939.     je cdn0
  3940.     add dh,1
  3941.     mov ah,2
  3942.     int bios
  3943. cdn0:    jmp telnoe
  3944.  
  3945. currt:    mov ah,3        ; Cursor right.
  3946.     mov bh,0
  3947.     int bios
  3948.     cmp dl,79
  3949.     je crt0
  3950.     add dl,1
  3951.     mov ah,2
  3952.     int bios
  3953. crt0:    jmp telnoe
  3954.  
  3955. curlft:    mov ah,3        ; Cursor left.
  3956.     mov bh,0
  3957.     int bios
  3958.     cmp dl,0
  3959.     je clt0
  3960.     sub dl,1
  3961.     mov ah,2
  3962.     int bios
  3963. clt0:    jmp telnoe
  3964.  
  3965. curskp:    jmp vtig        ; Ignore for now.
  3966.  
  3967. curclr:    call locate        ; Home the cursor [15]
  3968.     jmp curscr        ; And clear the screen [15]
  3969.  
  3970. curhm:    call locate
  3971.     jmp telnoe
  3972.  
  3973. curscr:    mov ah,3        ; Clear to end of screen.
  3974.     mov bh,0
  3975.     int bios
  3976.     cmp dx,0
  3977.     jne csr0
  3978.     call cmblnk
  3979.     jmp telnoe
  3980. csr0:    cmp dl,0
  3981.     je csr1
  3982.     push dx
  3983.     call clreol
  3984.     pop dx
  3985.     add dh,1
  3986.     mov dl,0
  3987. csr1:    mov cx,dx
  3988.     mov dx,184FH
  3989.     mov bh,7
  3990. ;    mov al,25
  3991. ;    sub al,ch
  3992.     mov al,0
  3993.     mov ah,7
  3994.     int bios
  3995.     jmp telnoe
  3996.  
  3997. curln:    call clreol        ; One routine to clear to EOL. [19a]
  3998.     jmp telnoe
  3999.  
  4000. inslin:    mov ah,3        ; Get cursor position.
  4001.     mov bh,0
  4002.     int bios
  4003.     mov temp,dx        ; Save here.
  4004.     mov cx,dx
  4005.     mov cl,0        ; Start at beginning of row.
  4006.     mov dx,184FH        ; End at lower corner of screen.
  4007.     mov ax,0701H
  4008.     mov bh,7
  4009.     int bios        ; Scroll down one line.
  4010.     mov dx,temp        ; Get back where we were.
  4011.     mov dl,0
  4012.     mov ah,2
  4013.     mov bh,0
  4014.     int bios
  4015.     jmp telnoe
  4016.  
  4017. dellin: mov ah,3
  4018.     mov bh,0
  4019.     int bios        ; Get current cursor position. 
  4020.     mov temp,dx        ; Remember the place.
  4021.     mov ax,0601H        ; Scroll up one line.
  4022.     mov cx,dx
  4023.     mov cl,0        ; Start at beginning of row.
  4024.     mov dx,184FH
  4025.     mov bh,7
  4026.     int bios
  4027.     mov dx,temp
  4028.     mov dl,0
  4029.     mov ah,2
  4030.     mov bh,0
  4031.     int bios
  4032.     jmp telnoe
  4033.  
  4034. ; Delete character.  [17b start] 
  4035. delchr:    mov ah,3        ; Get cursor position
  4036.     mov bh,0
  4037.     int bios
  4038.     mov temp,dx
  4039.     mov ah,1        ; Turn off cursor
  4040.     mov ch,20H
  4041.     int bios
  4042. delch1:    mov ah,2        ; Position to col M+1
  4043.     inc dl
  4044.     int bios
  4045.     mov ah,8        ; Get char/attr
  4046.     int bios
  4047.     mov cx,ax        ; Save it
  4048.     dec dl            ; Position to col M
  4049.     mov ah,2
  4050.     int bios
  4051.     mov ah,9        ; Write char/attr
  4052.     mov al,cl
  4053.     mov bl,ch
  4054.     mov cx,1
  4055.     int bios
  4056.     inc dl            ; Next column
  4057.     cmp dl,79        ; About to write to col 80?
  4058.     jne delch1        ; No
  4059.     mov ah,2        ; Position to col 80
  4060.     int bios
  4061.     mov ah,9        ; Write char/attr
  4062.     mov al,' '
  4063.     int bios
  4064.     mov ah,2        ; Reset cursor
  4065.     mov dx,temp
  4066.     int bios
  4067.     mov ah,1
  4068.     mov cx,0B0CH
  4069.     int bios
  4070.     jmp telnoe
  4071.  
  4072. ; Cancel Insert Character mode
  4073. insmox:    mov incmod,0
  4074.     jmp telnoe        ; [17b end]
  4075. TEL    ENDP
  4076.  
  4077. ; Common routine to clear to end-of-line. [19a]
  4078. CLREOL    PROC    NEAR
  4079.     mov ah,3        ; Clear to end of line.
  4080.     mov bh,0
  4081.     int bios        ; Get current cursor position
  4082.     mov cx,dx
  4083.     mov dl,79
  4084.     mov ah,7
  4085.     mov al,0
  4086.     mov bh,7
  4087.     int bios
  4088.     ret
  4089. CLREOL    ENDP
  4090. ENDIF    
  4091.  
  4092.  
  4093. ; This is the SET command.
  4094.  
  4095. SETCOM  PROC    NEAR
  4096.         mov dx,offset settab    ; Parse a keyword from the set table.
  4097.         mov bx,offset sethlp
  4098.         mov ah,cmkey
  4099.         call comnd
  4100.          jmp r
  4101.         call bx
  4102.         jmp rskp
  4103. SETCOM  ENDP
  4104.  
  4105.  
  4106. ;       This is the ESCAPE character SET subcommand.     [6 start]
  4107.  
  4108. ESCAPE  PROC    NEAR
  4109.     call cmgtch        ; Get a char.
  4110.     cmp ah,0
  4111.     jns es1            ; Terminator or no?
  4112.     and ah,7FH        ; Turn off minus bit.
  4113.     cmp ah,'?'
  4114.     jne es0
  4115.     mov dx,offset eschlp
  4116.     mov ah,prstr
  4117.     int dos
  4118.     mov dx,offset crlf
  4119.     int dos
  4120.     mov dx,offset kerm
  4121.     int dos
  4122.     mov bx,cmdptr
  4123.     mov al,'$'
  4124.     mov [bx],al
  4125.     mov dx,offset cmdbuf
  4126.     int dos
  4127.     dec cmcptr        ; Ignore dollar sign.
  4128.     dec cmccnt
  4129.     mov cmaflg,0
  4130.     jmp repars
  4131. es0:    mov ah,prstr
  4132.     mov dx,offset ermes3
  4133.     int dos
  4134.     ret
  4135. es1:      mov temp,ax
  4136.     call cmcfrm
  4137.      jmp es0
  4138.      nop            ; Take up 3 bytes.
  4139.     mov ax,temp
  4140.     mov escchr,ah        ; Save new value.
  4141.     ret
  4142. ESCAPE  ENDP            ; [6 end]
  4143.  
  4144. ;     This is the End-of-line character SET subcommand.       [5 start]
  4145.  
  4146. EOLSET    PROC    NEAR
  4147.     call cmgtch        ; Get the first char into AH.
  4148.     cmp ah,0
  4149.     jns eol1
  4150.     cmp ah,0BFH        ; Question mark?
  4151.     je eol4
  4152.     jmp eol3
  4153. eol1:    sub ah,030H        ; Digit --> real number.
  4154.     mov temp,ax        ; Save the input.
  4155.     call cmcfrm
  4156.      jmp eol0        ; Got a char.
  4157.     mov ax,0
  4158.     mov bx,temp
  4159.     jmp eol2
  4160. eol0:    sub ah,030H        ; Digit --> real number.
  4161.     mov temp1,ax
  4162.     call cmcfrm
  4163.      jmp eol3        ; Too many chars.
  4164.     mov bx,temp1
  4165.     mov ax,temp
  4166.     xchg al,ah
  4167.     mov ah,0
  4168. eol2:    mov temp,ax        ; Save our registers.
  4169.     mov temp1,bx
  4170.     call cmcfrm
  4171.      jmp eol3
  4172.     mov bx,temp1
  4173.     mov ax,temp
  4174.     mov temp2,10        ; Get numerical value of char.
  4175.     mul temp2
  4176.     add al,bh
  4177.     mov ah,0
  4178.     cmp al,0
  4179.     jl eol3
  4180.     cmp al,1FH
  4181.     jg eol3
  4182.     mov seol,al        ; Use new eol char.
  4183.     ret
  4184. eol3:    mov ah,prstr
  4185.     mov dx,offset eolerr    ; Bad end-of-line char
  4186.     int dos
  4187.     jmp prserr
  4188. eol4:    mov ah,prstr
  4189.     mov dx,offset eolhlp
  4190.     int dos
  4191.     mov dx,offset crlf
  4192.     int dos
  4193.     mov dx,offset kerm
  4194.     int dos
  4195.     mov bx,cmdptr
  4196.     mov al,'$'
  4197.     mov [bx],al
  4198.     mov dx,offset cmdbuf
  4199.     int dos
  4200.     dec cmcptr            ; Don't count the dollar sign.
  4201.     dec cmccnt            ; Or the question mark.
  4202.     mov cmaflg,0            ; Check for more input.
  4203.     jmp repars
  4204. EOLSET    ENDP                             ;    [5 end]
  4205.  
  4206. ;       This is the LOCAL echo SET subcommand.
  4207.  
  4208. LCAL    PROC    NEAR
  4209.         mov dx,offset ontab
  4210.         mov bx,offset onhlp
  4211.         mov ah,cmkey
  4212.         call comnd
  4213.          jmp r
  4214.         push bx                 ; Save the parsed value.
  4215.         mov ah,cmcfm
  4216.         call comnd              ; Get a confirm.
  4217.          jmp r                  ;  Didn't get a confirm.
  4218.         pop bx
  4219.         mov ecoflg,bl           ; Set the local echo flag.
  4220.     ret
  4221. LCAL    ENDP
  4222.  
  4223. ;       This is the VT52 emulation SET subcommand.
  4224.  
  4225. IF ibmpc
  4226. VT52EM  PROC    NEAR
  4227.         mov dx,offset ontab
  4228.         mov bx,offset onhlp
  4229.         mov ah,cmkey
  4230.         call comnd
  4231.          jmp r
  4232.         push bx
  4233.         mov ah,cmcfm
  4234.         call comnd              ; Get a confirm.
  4235.          jmp r                  ;  Didn't get a confirm.
  4236.         pop bx
  4237.         mov vtflg,bl            ; Set the VT52 emulation flag.
  4238.     ret
  4239. VT52EM  ENDP
  4240. ENDIF
  4241.  
  4242. ; This is the SET subcommand to choose between COM1 and COM2. [19b]
  4243.   
  4244. IF ibmpc
  4245. COMSET  PROC    NEAR
  4246.         mov dx,offset comptab
  4247.         mov bx,offset comphlp
  4248.         mov ah,cmkey
  4249.         call comnd
  4250.          jmp r
  4251.         push bx
  4252.         mov ah,cmcfm
  4253.         call comnd              ; Get a confirm.
  4254.          jmp r                  ;  Didn't get a confirm.
  4255.         pop bx
  4256.         mov comflg,bl           ; Set the comm port flag.
  4257.     call dobaud        ; Set the baud rate for the port. [19a]
  4258.     cmp comflg,1        ; Using Com 1?
  4259.     jne coms0        ; Nope.
  4260.     mov mddat,MDMDAT1    ; Set COM1 defaults.
  4261.     mov mdstat,MDMSTS1
  4262.     mov mdcom,MDMCOM1
  4263.     mov mddis,MDMINTC
  4264.     mov mden,MDMINTO
  4265.     mov mdmeoi,EOICOM
  4266.     mov mdintv,MDMINTV
  4267.     ret
  4268. coms0:    mov mddat,MDMDAT2    ; Set COM2 defaults.
  4269.     mov mdstat,MDMSTS2
  4270.     mov mdcom,MDMCOM2
  4271.     mov mddis,MDINTC2
  4272.     mov mden,MDINTO2
  4273.     mov mdmeoi,EOICOM2
  4274.     mov mdintv,MDINTV2
  4275.     ret
  4276. COMSET  ENDP
  4277. ENDIF
  4278.  
  4279. ;       This is the SET IBM command.
  4280.  
  4281. IBMSET  PROC    NEAR
  4282.         mov dx,offset ontab
  4283.         mov bx,offset onhlp
  4284.         mov ah,cmkey
  4285.         call comnd
  4286.          jmp r
  4287.         push bx
  4288.         mov ah,cmcfm
  4289.         call comnd              ; Get a confirm.
  4290.          jmp r                  ;  Didn't get a confirm.
  4291.         pop bx
  4292.         mov ibmflg,bl           ; Set the IBM flag.
  4293.     cmp bl,0        ; Turning on or off?    [12 start]
  4294.     je ibmst1        ; If off, set parity & local echo to defaults.
  4295.     mov ah,ibmpar        ; Set IBM parity.
  4296.     mov al,1        ; Set local echo on.
  4297.     jmp ibmst2
  4298. ibmst1:    mov ah,defpar        ; Reset parity to default.
  4299.     mov al,0        ; Turn off local echo.
  4300. ibmst2:    mov parflg,ah        ; Set parity.
  4301.     mov ecoflg,al        ; And local echo.    [12 end]    
  4302.     xor al,01H        ; 01 -> 00, 00 -> 01. [19c]  
  4303.     mov delflg,al        ; BS -> DEL or BS -> BS. [19c]
  4304.     ret
  4305. IBMSET  ENDP
  4306.  
  4307. ;       This is the SET File-Warning command.
  4308.  
  4309. FILWAR  PROC    NEAR
  4310.         mov dx,offset ontab
  4311.         mov bx,offset onhlp
  4312.         mov ah,cmkey
  4313.         call comnd
  4314.          jmp r
  4315.         push bx
  4316.         mov ah,cmcfm
  4317.         call comnd              ; Get a confirm.
  4318.          jmp r                  ;  Didn't get a confirm.
  4319.         pop bx
  4320.         mov flwflg,bl           ; Set the IBM flag.
  4321.     ret
  4322. FILWAR  ENDP
  4323.  
  4324. ;       This is the SET aborted-file command.  [20d]
  4325.  
  4326. ABFSET  PROC    NEAR
  4327.         mov dx,offset abftab
  4328.         mov bx,offset abfhlp
  4329.         mov ah,cmkey
  4330.         call comnd
  4331.          jmp r
  4332.         push bx
  4333.         mov ah,cmcfm
  4334.         call comnd              ; Get a confirm.
  4335.          jmp r                  ;  Didn't get a confirm.
  4336.         pop bx
  4337.         mov abfflg,bl           ; Set the aborted file flag.
  4338.     ret
  4339. ABFSET  ENDP
  4340.  
  4341. ;       This is the SET Parity command.                [10 start]
  4342.  
  4343. SETPAR  PROC    NEAR
  4344.         mov dx,offset partab
  4345.         mov bx,offset parhlp
  4346.         mov ah,cmkey
  4347.         call comnd
  4348.          jmp r
  4349.         push bx
  4350.         mov ah,cmcfm
  4351.         call comnd              ; Get a confirm.
  4352.          jmp r                  ;  Didn't get a confirm.
  4353.         pop bx
  4354.         mov parflg,bl           ; Set the parity flag.
  4355.     ret
  4356. SETPAR  ENDP                            ; [10 end]
  4357.  
  4358. ; Sets debugging mode on and off.
  4359.  
  4360. DEBST    PROC    NEAR
  4361.         mov dx,offset ontab
  4362.         mov bx,offset onhlp
  4363.         mov ah,cmkey
  4364.         call comnd
  4365.          jmp r
  4366.         push bx
  4367.         mov ah,cmcfm
  4368.         call comnd              ; Get a confirm.
  4369.          jmp r                  ;  Didn't get a confirm.
  4370.         pop bx
  4371.         mov debug,bl           ; Set the IBM flag.
  4372.     ret
  4373. DEBST   ENDP
  4374.  
  4375. ; Turn bell on or off.    [17a start]
  4376.  
  4377. BELLST    PROC    NEAR
  4378.     mov dx,offset ontab
  4379.     mov bx,offset onhlp
  4380.     mov ah,cmkey
  4381.     call comnd
  4382.      jmp r
  4383.     push bx
  4384.     mov ah,cmcfm
  4385.     call comnd
  4386.      jmp r
  4387.     pop bx
  4388.     mov belflg,bl
  4389.     ret
  4390. BELLST    ENDP                      ;  [17a end]
  4391.  
  4392. ; Function to set BS -> BS or BS -> DEL.  [19c]
  4393.  
  4394. BSSET    PROC    NEAR
  4395.         mov dx,offset BStab
  4396.         mov bx,offset BShlp
  4397.         mov ah,cmkey
  4398.         call comnd
  4399.          jmp r
  4400.         push bx
  4401.         mov ah,cmcfm
  4402.         call comnd              ; Get a confirm.
  4403.          jmp r                  ;  Didn't get a confirm.
  4404.         pop bx
  4405.         mov delflg,bl           ; Set backspace/delete flag.
  4406.     ret
  4407. BSSET   ENDP
  4408.  
  4409. ;  This function sets the baud rate.
  4410.  
  4411. BAUDST  PROC    NEAR
  4412.         mov dx,offset bdtab
  4413.         mov bx,offset bdhlp
  4414.         mov ah,cmkey
  4415.         call comnd
  4416.          jmp r
  4417.     push bx
  4418.     mov ah,cmcfm
  4419.     call comnd        ; Get a confirm.
  4420.      jmp r            ; Didn't get one.
  4421.     pop bx
  4422. IF ibmpc
  4423.         mov baud,bx             ; Set the IBM flag.
  4424.     call dobaud        ; Use common code. [19a] 
  4425. ENDIF
  4426. IF Z100 
  4427.     mov baud,bl        ; Remember baud rate. [20g]
  4428.     mov bx,ds        ; Set up pointer to config info
  4429.     mov es,bx        ;  .  .  .
  4430.     mov bx,offset auxcnf    ;  .  .  .
  4431.     mov ah,chr_control    ; Function is control
  4432.     mov al,chr_cfsu        ; Subfunction is set new config
  4433.     call bios_auxfunc    ; Set the configuration
  4434. ENDIF
  4435.     ret
  4436. BAUDST  ENDP
  4437.  
  4438. ; Only keep one copy of the code that sets the baud rate. [19a]
  4439.  
  4440. DOBAUD    PROC    NEAR
  4441. IF ibmpc
  4442.     mov dx,mdcom        ; LCR -- Initialize baud rate. [19b]
  4443.     in al,dx
  4444.     mov bl,al
  4445.     or ax,80H
  4446.     out dx,al
  4447.     mov dx,mddat        ; [19b]
  4448.     mov ax,baud
  4449.     out dx,al
  4450.     inc dx
  4451.     mov al,ah
  4452.     out dx,al
  4453.     mov dx,mdcom        ; [19b]
  4454.     mov al,bl
  4455.     out dx,al
  4456. ENDIF
  4457. IF Z100
  4458.     mov bx,ds        ; Set up pointer to config info
  4459.     mov es,bx        ;  .  .  .
  4460.     mov bx,offset auxcnf    ;  .  .  .
  4461.     mov ah,chr_status    ; Get the function code
  4462.     mov al,chr_sfgc        ; And the subfunction to get config
  4463.     call bios_auxfunc    ; Get the block
  4464. ENDIF
  4465.     ret
  4466. DOBAUD    ENDP
  4467.  
  4468. ;       This is the STATUS command.
  4469.  
  4470. STATUS  PROC    NEAR
  4471.         call stat0
  4472.          jmp r
  4473.         jmp rskp
  4474. STATUS  ENDP
  4475.  
  4476. STAT0   PROC    NEAR
  4477.         mov ah,cmcfm
  4478.         call comnd              ; Get a confirm.
  4479.          jmp r                  ;  Didn't get a confirm.
  4480. stat01: mov dx,offset locst     ; Assume local echo on.
  4481.     cmp ecoflg,0            ; Is the local echo flag on?
  4482.         jnz stat1               
  4483.         mov dx,offset remst     ; If not say so.
  4484. stat1:  mov ah,prstr            ; Print it.
  4485.         int dos
  4486. IF ibmpc
  4487.         mov dx,offset vtemst    ; Get address of the VT52 emulation string.
  4488.         cmp vtflg,0             ; Is the VT52 emulation flag on?
  4489.         jnz stat2
  4490.         mov dx,offset novtst    ; If not say so.
  4491. stat2:  mov ah,prstr            ; Print it.
  4492.         int dos
  4493.     mov dx,offset cm1st    ; Assume we're using COM1. [19b start]
  4494.     cmp comflg,1        ; Are we?
  4495.     je stat2a        ; Yup.
  4496.     mov dx,offset cm2st    ; We're using COM2.
  4497. stat2a:    mov ah,prstr
  4498.     int dos            ; [19b end]
  4499. ENDIF
  4500.     mov dx,offset ibmst    ; Is IBM flag on?
  4501.     cmp ibmflg,0
  4502.     jnz stat3
  4503.     mov dx,offset noibm     ; Say it's not.
  4504. stat3:  mov ah,prstr
  4505.     int dos
  4506.     mov dx,offset deboff    ; Assume debug mode is off.
  4507.     cmp debug,0
  4508.     je stat4
  4509.     mov dx,offset debon
  4510. stat4:    mov ah,prstr
  4511.     int dos
  4512.     mov dx,offset flwon    ; Assume file-warning on.
  4513.     cmp flwflg,0
  4514.     jne stat5
  4515.     mov dx,offset flwoff
  4516. stat5:    mov ah,prstr
  4517.     int dos
  4518.     mov dx,offset pnonst    ; Assume no parity.        [10 start]
  4519.     cmp parflg,parnon
  4520.     je stat6
  4521.     mov dx,offset pmrkst    ; Mark parity?
  4522.     cmp parflg,parmrk
  4523.     je stat6
  4524.     mov dx,offset pevnst    ; Maybe it's even parity.
  4525.     cmp parflg,parevn
  4526.     je stat6
  4527.     mov dx,offset poddst    ; Odd parity?
  4528.     cmp parflg,parodd
  4529.     je stat6
  4530.     mov dx,offset pspcst
  4531. stat6:    mov ah,prstr
  4532.     int dos                            ;[10 end]
  4533.     mov dx,offset belon    ; Tell if bells ring at end.  [17a start - DT]
  4534.     cmp belflg,0
  4535.     jne stat7
  4536.     mov dx,offset beloff    ; No bells. 
  4537. stat7:    mov ah,prstr
  4538.     int dos            ; That's it.  [17a end - DT]
  4539.     mov dx,offset abfdst    ; Do we discard file if abort? [20d start]
  4540.     cmp abfflg,1
  4541.     je stat8
  4542.     mov dx,offset abfkst    ; Keep what we received so far.
  4543. stat8:    int dos            ; [20d end]
  4544.     mov dx,offset bkdel    ; Is backarrow BS or DEL...  [19c start]
  4545.     cmp delflg,1        ; Is it delete?
  4546.     je stat9        ; Yup.
  4547.     mov dx,offset bkbs    ; It's a backspace.
  4548. stat9:    int dos            ; Tell the user.  [19c end]
  4549.     mov dx,offset eolst    ; Tell the end-of-line char used.  [5 start]
  4550.     mov ah,prstr
  4551.     int dos
  4552.     mov ah,conout
  4553.     mov dl,seol
  4554.     add dl,40H
  4555.     int dos                             ; [5 end]
  4556.     mov ah,prstr
  4557.     mov dx,offset escmes            ; Print escape character.  [6]
  4558.     int dos    
  4559.     call escprt
  4560.     call baudprt            ; Print the baud rate. [19a]
  4561.         mov dx,offset cmcrlf    ; Get the address of a crlf.
  4562.         mov ah,prstr            ; Print it.
  4563.         int dos
  4564.         jmp rskp
  4565. STAT0   ENDP
  4566.  
  4567. ; Print information on the baud rate. [19a]
  4568.  
  4569. BAUDPRT    PROC     NEAR
  4570.     mov dx,offset b48st    ; Assume 4800 baud.
  4571.     cmp baud,B4800
  4572.     jnz bdprt0
  4573.     jmp bdprt2
  4574. bdprt0:    mov dx,offset b12st
  4575.     cmp baud,B1200
  4576.     jnz bdprt1
  4577.     jmp bdprt2
  4578. bdprt1:    mov dx,offset b18st
  4579.     cmp baud,B1800
  4580.     jz bdprt2
  4581.     mov dx,offset b24st
  4582.     cmp baud,B2400
  4583.     jz bdprt2
  4584.     mov dx,offset b96st
  4585.     cmp baud,B9600
  4586.     jz bdprt2
  4587.     mov dx,offset b03st
  4588. IF ibmpc
  4589.     jmp bdprt2
  4590. ENDIF
  4591. IF Z100
  4592.     cmp baud,B0300
  4593.     jz bdprt2
  4594.     mov dx,offset b04st
  4595.     cmp baud,B00455
  4596.     jz bdprt2
  4597.     mov dx,offset b05st
  4598.     cmp baud,B0050
  4599.     jz bdprt2
  4600.     mov dx,offset b07st
  4601.     cmp baud,b0075
  4602.     jz bdprt2
  4603.     mov dx,offset b11st
  4604.     cmp baud,B0110
  4605.     jz bdprt2
  4606.     mov dx,offset b13st
  4607.     cmp baud,B01345
  4608.     jz bdprt2
  4609.     mov dx,offset b15st
  4610.     cmp baud,B0150
  4611.     jz bdprt2
  4612.     mov dx,offset b06st
  4613.     cmp baud,B0600
  4614.     je bdprt2
  4615.     mov dx,offset b20st
  4616.     cmp baud,B2000
  4617.     jz bdprt2
  4618.     mov dx,offset b19st
  4619.     cmp baud,B19200
  4620.     jz bdprt2
  4621.     mov dx,offset b38st
  4622. ENDIF
  4623. bdprt2:    mov ah,prstr
  4624.     int dos
  4625.     ret
  4626. BAUDPRT    ENDP
  4627.  
  4628. ;       Utility routines
  4629.  
  4630. ; Jumping to this location is like retskp.  It assumes the instruction
  4631. ;   after the call is a jmp addr.
  4632.  
  4633. RSKP    PROC    NEAR
  4634.     pop bp
  4635.     add bp,3
  4636.     push bp
  4637.         ret
  4638. RSKP    ENDP
  4639.  
  4640. ; Jumping here is the same as a ret.
  4641.  
  4642. R       PROC    NEAR
  4643.         ret
  4644. R       ENDP
  4645.  
  4646. ; This routine prints the number in AX on the screen.  (Thanks to Jeff
  4647. ; Damens).  No longer used but keep around just in case.
  4648.  
  4649. ;NOUT    PROC    NEAR
  4650. ;        push bx                 ; Save some stuff.
  4651. ;        push cx
  4652. ;        push dx
  4653. ;        push ax
  4654. ;        mov bh,0                ; Don't print leading zeros.
  4655. ;        and ah,0F0H             ; Only want high order nibble.
  4656. ;        mov cl,4
  4657. ;    shr ah,cl
  4658. ;        call pdig               ; Print the digit.
  4659. ;        pop ax                  ; Restore argument.
  4660. ;        and ah,0FH              ; Just the low order nibble.
  4661. ;        call pdig
  4662. ;        mov ah,al
  4663. ;        and ah,0F0H             ; Only want high order nibble.
  4664. ;    mov cl,4
  4665. ;        shr ah,cl
  4666. ;        call pdig               ; Print the digit.
  4667. ;        mov ah,al
  4668. ;        and ah,0FH              ; Just the low order nibble.
  4669. ;        mov bh,0FFH             ; Make sure at least one zero is printed.
  4670. ;        call pdig
  4671. ;        pop dx                  ; Restore some stuff.
  4672. ;        pop cx
  4673. ;        pop bx
  4674. ;        ret
  4675. ;NOUT    ENDP
  4676.  
  4677.  ; Print the number in AX on the screen in decimal rather that hex. [19a]
  4678.  
  4679. NOUT     PROC    NEAR
  4680.     push ax
  4681.     push dx
  4682.     mov temp,10        ; Divide quotient by 10.
  4683.     cwd            ; Convert word to doubleword.
  4684.     div temp        ; AX <-- Quo, DX <-- Rem.
  4685.     cmp ax,0        ; Are we done?    
  4686.     jz nout0        ; Yes.
  4687.     call nout        ; If not, then recurse.
  4688. nout0:    add dl,'0'        ; Make it printable.
  4689.     mov temp,ax
  4690.     mov ah,conout
  4691.     int dos    
  4692.     mov ax,temp
  4693.     pop dx
  4694.     pop ax
  4695.     ret
  4696. NOUT    ENDP
  4697.  
  4698.        ; print the digit in register AH
  4699.  
  4700. PDIG    PROC    NEAR
  4701.         push ax                 ; Save it.
  4702.         cmp ah,0
  4703.         jne pdig2
  4704.         cmp bh,0
  4705.         jne pdig2
  4706.         pop ax
  4707.         ret
  4708. pdig2:  mov bh,0FFH             ; Set the print zero flag.
  4709.         cmp ah,10               ; Do we use digits or a-f?
  4710.         jl usedig               ; Digit.
  4711.         add ah,'A'-10           ; Compute digit
  4712.         jmp havdig              ; and proceed.
  4713. usedig: add ah,'0'              ; Convert to digit
  4714. havdig: mov dl,ah
  4715.         mov ah,conout
  4716.         int dos
  4717.         pop ax
  4718.         ret
  4719. PDIG    ENDP
  4720.  
  4721.  
  4722. ;       This set of routines provides a user oriented way of parsing
  4723. ;       commands.  It is similar to that of the COMND JSYS in TOPS-20.
  4724.  
  4725.  
  4726. ;       This routine prints the prompt in DE and specifies the reparse
  4727. ;       address.
  4728.  
  4729. PROMPT    PROC  NEAR
  4730.     pop bx                  ; Get the return address.
  4731.         push bx                 ; Put it on the stack again.
  4732.         mov cmrprs,bx           ; Save as addr to go to on reparse.
  4733.         mov bx,0                        ; Clear out register.
  4734.         add bx,sp               ; Get the present stack pointer.
  4735.         mov cmostp,bx           ; Save for later restoral.
  4736.         mov cmprmp,dx           ; Save pointer to the prompt.
  4737.         mov bx,offset cmdbuf
  4738.         mov cmcptr,bx           ; Initialize the command pointer.
  4739.         mov cmdptr,bx
  4740.         mov ah,0
  4741.         mov cmaflg,ah           ; Zero the flags.
  4742.         mov cmccnt,ah
  4743.         mov cmsflg,0FFH
  4744.         mov ah,prstr
  4745.         mov dx,offset cmcrlf
  4746.         int dos
  4747.         mov ah,prstr            ; Print the prompt.
  4748.         mov dx,cmprmp
  4749.         int dos
  4750.         ret
  4751. PROMPT    ENDP
  4752.  
  4753. ;       This address is jumped to on reparse.
  4754.  
  4755. PARSE    PROC NEAR 
  4756. repars: mov sp,cmostp           ; new sp <-- old sp
  4757.         mov bx,offset cmdbuf
  4758.         mov cmdptr,bx
  4759.         mov ah,0FFH
  4760.         mov cmsflg,ah
  4761.         mov bx,cmrprs           ; Get the reparse address.
  4762.         call bx                 ; Go there.
  4763.  
  4764. ;       This address can be jumped to on a parsing error.
  4765.  
  4766. prserr: mov sp,cmostp           ; Set new sp to old one.
  4767.         mov bx,offset cmdbuf
  4768.         mov cmcptr,bx           ; Initialize the command pointer.
  4769.         mov cmdptr,bx
  4770.         mov ah,0
  4771.         mov cmaflg,ah           ; Zero the flags.
  4772.         mov cmccnt,ah
  4773.         mov cmsflg,0FFH
  4774.         mov ah,prstr
  4775.         mov dx,offset cmcrlf
  4776.         int dos
  4777.         mov ah,prstr            ; Print the prompt.
  4778.         mov dx,cmprmp           ; Get the prompt.
  4779.         int dos
  4780. ; Instead return to before the prompt call.
  4781.         mov bx,cmrprs
  4782.         call bx
  4783. PARSE    ENDP
  4784.  
  4785. ;       This routine parses the specified function in AH. Any additional
  4786. ;       information is in DX and BX.
  4787. ;       Returns +1 on success
  4788. ;               +4 on failure (assumes a JMP follows the call)
  4789.  
  4790. CMND    PROC NEAR
  4791. comnd:  mov cmstat,ah           ; Save what we are presently parsing.
  4792.         call cminbf             ; Get chars until an action or a erase char.
  4793.     mov ah,cmstat        ; Restore 'ah' for upcoming checks.
  4794.         cmp ah,cmcfm            ; Parse a confirm?
  4795.         jz cmcfrm               ; Go get one.
  4796.         cmp ah,cmkey            ; Parse a keyword?
  4797.     jnz cm1
  4798.         jmp cmkeyw               ; Try and get one.
  4799. cm1:    cmp ah,cmifi        ; Parse an input file spec?
  4800.     jnz cm2
  4801.     jmp cmifil        ; Go get one.
  4802. cm2:    cmp ah,cmofi        ; Output file spec?
  4803.     jnz cm3
  4804.     jmp cmofil        ; Go get one.
  4805. cm3:    cmp ah,cmtxt        ; Parse arbitrary text.   [8]
  4806.     jnz cm4
  4807.     jmp cmtext
  4808. cm4:    mov ah,prstr        ; Else give error.
  4809.     mov dx,offset cmer00    ; "?Unrecognized COMND call"
  4810.     int dos
  4811.     ret
  4812.  
  4813. ; This routine gets a confirm.
  4814.  
  4815. cmcfrm: call cmgtch        ; Get a char.
  4816.     cmp ah,0        ; Is it negative (a terminator; a space or
  4817.                 ; a tab will not be returned here as they
  4818.                 ; will be seen as leading white space.)
  4819.         js cmcfr0
  4820.         ret                     ; If not, return failure.
  4821. cmcfr0: and ah,7FH                      ; Turn off the minus bit.
  4822.         cmp ah,esc                      ; Is it an escape?
  4823.         jne cmcfr2
  4824.         mov ah,conout
  4825.         mov dl,bell             ; Get a bell.
  4826.         int dos
  4827.         mov ah,0
  4828.         mov cmaflg,ah           ; Turn off the action flag.
  4829.         mov bx,cmcptr           ; Move the pointer to before thee scape.
  4830.         dec bx
  4831.         mov cmcptr,bx
  4832.         mov cmdptr,bx
  4833.         dec cmccnt              ; Decremrnt the char count.
  4834.         jmp cmcfrm              ; Try again.
  4835. cmcfr2: cmp ah,'?'                      ; Curious?
  4836.         jne cmcfr3
  4837.         mov ah,prstr            ; Print something useful.
  4838.         mov dx,offset cmin00
  4839.         int dos
  4840.         mov ah,prstr
  4841.         mov dx,offset cmcrlf            ; Print a crlf.
  4842.         int dos
  4843.         mov ah,prstr
  4844.         mov dx,cmprmp           ; Reprint the prompt.
  4845.         int dos
  4846.         mov bx,cmdptr           ; Get the pointer into the buffer.
  4847.         mov ah,'$'              ; Put a $ there for printing.
  4848.         mov [bx],ah
  4849.         mov bx,cmcptr
  4850.         dec bx                  ; Decrement & save the buffer pointer.
  4851.         mov  cmcptr,bx
  4852.         mov ah,prstr
  4853.         mov dx,offset cmdbuf
  4854.         int dos
  4855.         mov ah,0                        ; Turn off the action flag.
  4856.         mov cmaflg,ah
  4857.         jmp repars              ; Reparse everything.
  4858.  
  4859. cmcfr3: cmp ah,ff                       ; Is it a form feed?
  4860.         jne cmcfr4
  4861.         call cmblnk             ; If so blank the screen.
  4862. cmcfr4: jmp rskp
  4863.  
  4864. ;       This routine parses a keyword from the table pointed
  4865. ;       to in DX.  The format of the table is as follows:
  4866. ;
  4867. ;       addr:   db      n       ; Where n is the # of entries in the table.
  4868. ;               db      m       ; M is the size of the keyword.
  4869. ;               db      'string$' ; Where string is the keyword.
  4870. ;               dw      ab      ; Where ab is data to be returned.
  4871. ;
  4872. ;       The keywords must be in alphabetical order.
  4873.  
  4874.  
  4875. cmkeyw: mov cmhlp,bx            ; Save the help.
  4876.         mov cmptab,dx           ; Save the beginning of keyword table.
  4877.         mov bx,dx
  4878.         mov ch,[bx]                     ; Get number of entries in table.
  4879.         inc bx
  4880.     mov dx,cmdptr        ; Save command pointer.
  4881.     mov cmsptr,dx        ; Save pointer's here.
  4882. cmky1:  cmp ch,0                ; Any commands left to check?
  4883.         jne cmky2
  4884. ;    mov ah,prstr        ; [19e]
  4885. ;    mov dx,offset cmer04    ; Complain.   [1] [19e]
  4886. ;    int dos            ; [19e]
  4887.         ret                     ; Fail if not.
  4888. cmky2:  dec ch
  4889.     mov cl,0        ; Keep track of how many chars read in so far.
  4890.         call cmgtch             ; Get a char.
  4891.         cmp ah,0                ; Do we have a terminator?
  4892.         jns cmky2x 
  4893.     jmp cmky4               ; Negative number means we do.
  4894. cmky2x: inc bx                  ; Point to first letter of keyword.
  4895.     inc cl            ; Read in another char.
  4896.         mov al,[bx]                   
  4897.         cmp ah,'a'              ; Less than a?
  4898.         jl cmky21               ; If so, don't capitalize.
  4899.         cmp ah,'z'+1            ; More than z?
  4900.         jns cmky21
  4901.         and ah,137O             ; Capitalize the letter.
  4902. cmky21: cmp ah,al
  4903.     je cmky3
  4904.     jg cmky2y
  4905.         jmp cmky41              ; Fail if ah preceeds al alphabetically.
  4906. cmky2y: jmp cmky6               ; Not this keyword - try the next.
  4907. cmky3:  inc bx                  ; We match here, how 'bout next char?
  4908.         mov al,[bx]
  4909.         cmp al,'$'               ; End of keyword?
  4910.     jne cmky3x
  4911.         jmp cmky7                ; Succeed.
  4912. cmky3x:    mov dl,al        ; Save al's char here.
  4913.         call cmgtch
  4914.     inc cl            ; Read in another char.
  4915.     mov al,dl
  4916.     cmp ah,'a'
  4917.     jl cmky31
  4918.     cmp ah,'z'+1
  4919.     jns cmky31
  4920.     and ah,137O
  4921. cmky31: cmp ah,9BH        ; Escape Recognition (escape w/minus bit on)?
  4922.     je cmky3y
  4923.     cmp ah,0BFH        ; A question mark?    [3]
  4924.     je cmky3y
  4925.     cmp ah,0A0H        ; A space?
  4926.     je cmky3y
  4927.     cmp ah,8DH        ; Carriage return?
  4928.     je cmky3y
  4929.     jmp cmky38
  4930. cmky3y:    mov cmkptr,bx        ; Save bx here.
  4931.     mov cmsiz,cx        ; Save size info.
  4932.     mov cmchr,ah        ; Save char for latter.
  4933.     call cmambg        ; See if input is ambiguous or not.
  4934.      jmp cmky32        ; Succeeded (not ambiguous).
  4935.     mov ah,cmchr
  4936.     cmp ah,9BH        ; Escape?
  4937.     je cmky3z
  4938.     jmp cmky41        ; Fail.
  4939. cmky3z:    mov ah,conout        ; Else, ring a bell.
  4940.     mov dl,bell
  4941.     int dos
  4942.     mov bx,cmcptr        ; Move pointer to before the escape.
  4943.     dec bx
  4944.     mov cmcptr,bx
  4945.     mov cmdptr,bx
  4946.     dec cmccnt        ; Decrement char count.
  4947.     mov bx,cmkptr        ; Failed - pretend user never typed ....
  4948.     mov cx,cmsiz        ; ... in a char.
  4949.     dec cl            ; Don't count the escape.
  4950.     dec bx
  4951.     mov cmaflg,0        ; Reset the action flag.
  4952.     jmp cmky3        ; Keep checking.
  4953. cmky32: mov cx,cmsiz        ; Restore info.
  4954.     mov bx,cmkptr        ; Our place in the keyword table.
  4955.     cmp cmchr,0A0H        ; Space?
  4956.     je cmky35
  4957.     cmp cmchr,0BFH        ; Question mark?     [3]
  4958.     je cmky35
  4959.     cmp cmchr,8DH        ; Carriage return?
  4960.     je cmky35
  4961.     dec cmcptr        ; Pointer into buffer of input.
  4962.     mov dx,cmcptr
  4963. cmky33:    mov ah,[bx]        ; Get next char in keyword.
  4964.     cmp ah,'$'        ; Are we done yet?
  4965.     jz cmky34
  4966.     mov di,dx
  4967.     mov [di],ah
  4968.     inc bx
  4969.     inc dx
  4970.     inc cmccnt
  4971.     jmp cmky33
  4972. cmky34:    mov ah,' '
  4973.     mov di,dx
  4974.     mov [di],ah        ; Put a blank in the buffer.
  4975.     inc dx
  4976.     mov cx,cmcptr        ; Remember where we were (for printing below).
  4977.     mov cmcptr,dx        ; Update our pointers.
  4978.     mov cmdptr,dx
  4979.     mov ah,'$'
  4980.     mov di,dx
  4981.     mov [di],ah        ; Add '$' for printing.
  4982.     mov ah,prstr
  4983.     mov dx,cx        ; Point to beginning of filled in data.
  4984.     int dos
  4985.     inc bx            ; Point to address we'll need.
  4986.     mov bx,[bx]
  4987.     mov cmaflg,0         ; Turn off action flag.
  4988.     jmp rskp
  4989.  
  4990. cmky35:    inc bx
  4991.     mov ah,[bx]        ; Find end of keyword. 
  4992.     cmp ah,'$'
  4993.     jne cmky35    
  4994.     inc bx
  4995.     mov bx,[bx]        ; Address of next routine to call.
  4996. ;    mov cmaflg,0        ; Zero the action flag.
  4997.     jmp rskp
  4998.  
  4999. cmky38:    cmp ah,al
  5000.         jne cmky6               ; Go to end of keyword and try next.
  5001.         jmp cmky3
  5002.            
  5003. cmky4:  and ah,7FH              ; Turn off minus bit.
  5004.         cmp ah,'?'              ; Need help?
  5005.         je cmky5
  5006.     cmp ah,' '        ; Just a space - no error.
  5007.     je cmky51
  5008.     cmp ah,cr
  5009.     je cmky51
  5010.     cmp ah,tab
  5011.     je cmky51 
  5012.     cmp ah,esc        ; Ignore escape?
  5013.     je cmky43
  5014. cmky41: mov ah,prstr
  5015.         mov dx,offset cmer03
  5016.         int dos
  5017.         jmp prserr              ; Parse error - give up.
  5018.  
  5019. cmky43:    mov ah,conout        ; Ring a bell.
  5020.     mov dl,bell
  5021.     int dos
  5022.     mov bx,cmcptr
  5023.     dec bx
  5024.     mov cmcptr,bx
  5025.     mov cmdptr,bx
  5026.     dec cmccnt        ; Don't count the escape.
  5027.     mov cmaflg,0        ; Reset action flag.
  5028.     inc ch            ; Account for a previous 'dec'.
  5029.     jmp cmky1        ; Start over.
  5030.  
  5031. cmky5:  mov ah,prstr
  5032.         mov dx,cmhlp            ; Print the help text.
  5033.         int dos
  5034.     mov dx,offset crlf
  5035.     int dos
  5036.     mov dx,offset kerm
  5037.     int dos
  5038.     mov bx,cmdptr        ; Get pointer into buffer.
  5039.     mov al,'$'
  5040.     mov [bx],al        ; Add dollar sign for printing.
  5041.     mov dx,offset cmdbuf
  5042.     int dos
  5043.     dec cmcptr        ; Don't keep it in the buffer.
  5044.     dec cmccnt        ; Don't conut it.
  5045.     mov cmaflg,0            ; Turn off the action flag.
  5046.         jmp repars
  5047.  
  5048. cmky51:    jmp prserr
  5049.  
  5050. cmky6:  inc bx                  ; Find end of keyword.
  5051.         mov al,[bx]
  5052.         cmp al,'$'
  5053.         jne cmky6             
  5054.         inc bx                  ; Beginning of next command.
  5055.         inc bx
  5056.         inc bx
  5057.     mov dx,cmsptr        ; Get old cmdptr.
  5058.     mov cmdptr,dx        ; Restore.
  5059.     mov cmsflg,0FFH
  5060.         jmp cmky1               ; Keep trying.
  5061.  
  5062. cmky7:  call cmgtch             ; Get char.
  5063.     cmp ah,0
  5064.     js cmky71        ; Ok if a terminator.
  5065.         dec bx
  5066.         jmp cmky6               ; No match - try next keyword.
  5067. cmky71: inc bx                  ; Get necessary data.
  5068.         mov bx,[bx]
  5069.     cmp ah,9BH        ; An escape?
  5070.     jne cmky72
  5071.     mov ah,prstr
  5072.     mov dx,offset prsp      ; Print a space.
  5073.     int dos
  5074.     mov di,cmcptr
  5075.     dec di
  5076.     mov ah,20H
  5077.     mov [di],ah        ; Replace escape char with space.
  5078.     mov cmaflg,0
  5079.     mov cmsflg,0FFH        ; Pretend they typed a space.
  5080. cmky72: jmp rskp
  5081.  
  5082. ; See if keyword is unambiguous or not from what the user has typed in.
  5083.  
  5084. cmambg:    cmp ch,0        ; Any keywords left to check?
  5085.     jne cmamb0
  5086.     ret            ; If not then not ambiguous.
  5087. cmamb0:    inc bx            ; Go to end of keyword ...
  5088.     mov al,[bx]        ; So we can check the next one.
  5089.     cmp al,'$'
  5090.     jne cmamb0
  5091.     add bx,4        ; Point to start of next keyword.
  5092.     dec cl            ; Don't count escape.
  5093.     mov dx,cmsptr        ; Buffer with input typed by user.
  5094. cmamb1:    mov ah,[bx]        ; Keyword char.    
  5095.     mov di,dx
  5096.     mov al,[di]        ; Input char.
  5097.     cmp al,'a'        ; Do capitalizing.
  5098.     jl cmam11
  5099.     cmp al,'z'+1
  5100.     jns cmam11
  5101.     and al,137O
  5102. cmam11:    cmp ah,al        ; Keyword bigger than input (alphabetically)?
  5103.     jle cmamb2        ; No - keep checking.
  5104.     ret            ; Yes - not ambiguous.
  5105. cmamb2:    inc bx            ; Advance one char.
  5106.     inc dx
  5107.     dec cl
  5108.     jnz cmamb1
  5109.     jmp rskp        ; Fail - it's ambiguous.
  5110.  
  5111. cmifil: mov bx,dx               ; Get the fcb address in bx.
  5112.         mov cmfcb,bx            ; Save it.
  5113.         mov ch,0                ; Initialize char count.
  5114.         mov ah,0
  5115.         mov [bx],ah                     ; Set the drive to default to current.
  5116.     inc bx
  5117.         mov cmfcb2,bx
  5118.         mov cl,' '
  5119. cmifi0: mov [bx],cl                     ; Blank the FCB.
  5120.         inc bx
  5121.         inc ah
  5122.         cmp ah,0BH                      ; Twelve?
  5123.         jl cmifi0
  5124. cmifi1: call cmgtch             ; Get another char.
  5125.         cmp ah,0                        ; Is it an action character.
  5126.         jns cmifi2
  5127.         and ah,7FH                      ; Turn off the action bit.
  5128.         cmp ah,'?'                      ; A question mark?
  5129.         jne cmif12
  5130.         mov al,0
  5131.         mov cmaflg,al           ; Blank the action flag.
  5132.         dec cmcptr           ; Decrement the buffer pointer.
  5133.     dec cmccnt        ; Decrement count.
  5134. ;        jmp cmifi8              ; Treat like any other character.
  5135.     mov ah,prstr
  5136.     mov dx,offset filhlp    ; Help  message.
  5137.     int dos
  5138.     mov dx,offset crlf
  5139.     int dos
  5140.     mov dx,offset kerm
  5141.     int dos
  5142.     mov bx,cmdptr
  5143.     mov al,'$'
  5144.     mov [bx],al        ; Put in dollar sign for printing.
  5145.     mov dx,offset cmdbuf
  5146.     int dos
  5147.     jmp repars
  5148. cmif12: cmp ah,esc                      ; An escape?
  5149.         jne cmif13
  5150.         mov ah,0
  5151.         mov cmaflg,ah           ; Turn off the action flag.
  5152.         mov ah,conout
  5153.         mov dl,bell
  5154.         int dos         ; Ring the bell.
  5155.         mov bx,cmcptr           ; Move the pointer to before the escape.
  5156.         dec bx
  5157.         mov cmcptr,bx
  5158.         mov cmdptr,bx
  5159.         dec cmccnt              ; Decrement char count.
  5160.         jmp repars
  5161. cmif13: mov ah,ch                       ; It must be a terminator.
  5162.         cmp ah,0                        ; Test the length of the file name.
  5163.     jnz cmf3x
  5164.         jmp cmifi9               ; If zero complain.
  5165. cmf3x:  cmp ah,0DH
  5166.         js cmf3y
  5167.     jmp cmifi9              ; If too long complain.
  5168. cmf3y:  jmp rskp                ; Otherwise we have succeeded.
  5169. cmifi2: cmp ah,'.'
  5170.         jne cmifi3
  5171.         inc ch
  5172.         mov ah,ch
  5173.         cmp ah,1H                       ; Any chars yet?
  5174.           jnz cmf2x
  5175.     jmp cmifi9               ; No, give error.
  5176. cmf2x:  cmp ah,0AH                      ; Tenth char?
  5177.           js cmf2y
  5178.     jmp cmifi9              ; Past it, give an error.
  5179. cmf2y:  mov dl,9H
  5180.         mov dh,0
  5181.         mov bx,cmfcb
  5182.         add bx,dx               ; Point to file type field.
  5183.         mov cmfcb2,bx
  5184.         mov ch,9H               ; Say we've gotten nine.
  5185.         jmp cmifi1              ; Get the next char.
  5186. cmifi3: cmp ah,':'
  5187.         jne cmifi4
  5188.         inc ch
  5189.         cmp ch,2H                       ; Is it in right place for a drive?
  5190.     je cmif3x
  5191.         jmp cmifi9              ; If not, complain.
  5192. cmif3x: mov ch,0        ; Reset char count.
  5193.     mov bx,cmfcb2
  5194.     sub bx,1
  5195.         mov ah,[bx]                     ; Get the drive name.
  5196.         sub ah,'@'              ; Get the drive number.
  5197.     mov cmfcb2,bx
  5198.      mov bx,cmfcb
  5199.         mov [bx],ah                     ; Put it in the fcb.
  5200.         jmp cmifi1
  5201. cmifi4: cmp ah,'*'
  5202.         jne cmifi7
  5203.         mov ah,ch
  5204.         cmp ah,8H                       ; Is this in the name or type field?
  5205.         jz cmifi9               ; If its where the dot should be give up.
  5206.         jns cmifi5              ; Type.
  5207.         mov cl,8H               ; Eight chars.
  5208.         jmp cmifi6
  5209. cmifi5: mov cl,0CH              ; Three chars.
  5210. cmifi6: mov wldflg,0FFH        ; Remember we had a wildcard.
  5211.     mov bx,cmfcb2           ; Get a pointer into the FCB.
  5212.         mov ah,'?'
  5213.         mov [bx],ah                     ; Put a question mark in.
  5214.         inc bx
  5215.         mov cmfcb2,bx
  5216.         inc ch
  5217.         mov ah,ch
  5218.         cmp ah,cl
  5219.         jl cmifi6               ; Go fill in another.
  5220.         jmp cmifi1              ; Get the next char.
  5221. cmifi7: cmp ah,03DH        ; Equals sign (wildcard)?
  5222.     jne cmif7x
  5223.     mov ah,'?'
  5224.     mov wldflg,0FFH        ; Say we have a wildcard.
  5225.     jmp cmifi8        ; Put into FCB.
  5226. cmif7x:    cmp ah,'0'
  5227.         jl cmif8x
  5228.         cmp ah,'z'+1
  5229.         jns cmif8x
  5230.         cmp ah,'A'                      ; Don't capitalize non-alphabetics.
  5231.         jl cmifi8
  5232.         and ah,137O             ; Capitalize.
  5233. cmifi8: mov bx,cmfcb2           ; Get the pointer into the FCB.
  5234.         mov [bx],ah                     ; Put the char there.
  5235.         inc bx
  5236.         mov cmfcb2,bx
  5237.         inc ch
  5238.         jmp cmifi1
  5239.  
  5240. cmif8x:    push es
  5241.     mov cx,ds
  5242.     mov es,cx        ; Scan uses ES register.
  5243.     mov di,offset spchar    ; Special chars.
  5244.     mov cx,20        ; Twenty of them.
  5245.     mov al,ah        ; Char is in al.
  5246.     repnz scasb        ; Search string for input char.
  5247.     cmp cx,0        ; Was it there?
  5248.     pop es
  5249.     jnz cmifi8
  5250.  
  5251. cmifi9: mov ah,prstr
  5252.         mov dx,offset cmer02
  5253.         int dos
  5254.         ret
  5255.  
  5256. cmofil: jmp cmifil              ; For now, the same as CMIFI.
  5257.  
  5258. ; Parse arbitrary text up to a CR.  Put chars into data buffer sent to
  5259. ; the host (pointed to by BX).   Return updated pointer in BX and 
  5260. ; input size in AH.
  5261.  
  5262. cmtext:    mov cmptab,bx        ; Save pointer to data buffer.   [8 start]
  5263.     mov cl,0        ; Init the char count.
  5264. cmtxt1:    call cmgtch        ; Get a char.
  5265.     cmp ah,0        ; Terminator?
  5266.     jns cmtxt5        ; Nope, put into the buffer.
  5267.     and ah,07FH
  5268.     cmp ah,esc        ; An escape?
  5269.     jne cmtxt2
  5270.     mov ah,conout
  5271.     mov dl,bell        ; Ring a bell.
  5272.     int dos
  5273.     mov cmaflg,0        ; Reset action flag.
  5274.     dec cmcptr        ; Move pointer to before the escape.
  5275.     dec cmdptr
  5276.     dec cmccnt        ; Decrement count.
  5277.     jmp cmtxt1        ; Try again.
  5278. cmtxt2:    cmp ah,'?'        ; Asking a question?
  5279.     jz cmtxt3
  5280.     cmp ah,ff        ; Formfeed?
  5281.     jne cmtx2x
  5282.     call cmblnk
  5283. cmtx2x: mov ah,cl        ; Return count in AH.
  5284.     mov bx,cmptab        ; Return updated pointer.
  5285.     jmp rskp
  5286. cmtxt3:    mov cmaflg,0        ; Reset action flag to zero.
  5287. cmtxt5: inc cl            ; Increment the count.
  5288.     mov bx,cmptab        ; Pointer into destination array.
  5289.     mov [bx],ah        ; Put char into the buffer.
  5290.     inc bx
  5291.     mov cmptab,bx
  5292.     jmp cmtxt1                    ; [8 end]
  5293.  
  5294. cminbf: push dx
  5295.         push bx
  5296.         mov cx,dx               ; Save value here too.
  5297.         mov ah,cmaflg           ; Is the action char flag set?
  5298.         cmp ah,0
  5299.     je cminb1
  5300.         jmp cminb9              ; If so get no more chars.
  5301. cminb1: inc cmccnt              ; Increment the char count.
  5302.         mov ah,conin            ; Get a char.
  5303.         int dos
  5304.     mov ah,al        ; Keep char in 'ah'.
  5305.         mov bx,cmcptr           ; Get the pointer into the buffer.
  5306.         mov [bx],ah                     ; Put it in the buffer.
  5307.         inc bx
  5308.         mov cmcptr,bx
  5309.         cmp ah,25O                      ; Is it a ^U?
  5310.         jne cminb2
  5311. cmnb12: mov ah,prstr
  5312.     mov dx,offset clrlin
  5313.     int dos
  5314. IF ibmpc
  5315.     mov ax,0920H               ; Write spaces.
  5316.         mov bx,7                ; Clear the line.
  5317.     mov cx,80
  5318.         int bios
  5319. ENDIF
  5320.         mov ah,prstr
  5321.         mov dx,cmprmp           ; Print the prompt.
  5322.         int dos
  5323.         mov bx,offset cmdbuf
  5324.         mov cmcptr,bx           ; Reset the point to the start.
  5325.     mov cmccnt,0               ; Zero the count.
  5326.         mov dx,cx               ; Preserve original value of dx.
  5327.         jmp repars              ; Go start over.
  5328. cminb2: cmp ah,10O                      ; Or backspace?
  5329.         jz cminb3
  5330.         cmp ah,del                      ; Delete?
  5331.         jne cminb4
  5332.         mov ah,prstr            ; Print the delete string.
  5333.         mov dx,offset delstr
  5334.         int dos
  5335. cminb3: mov ah,cmccnt           ; Decrement the char count by two.
  5336.         dec ah
  5337.         dec ah
  5338.         cmp ah,0                        ; Have we gone too far?
  5339.         jns cmnb32              ; If not proceed.
  5340.         mov ah,conout           ; Ring the bell.
  5341.         mov dl,bell
  5342.         int dos
  5343.         jmp cmnb12              ; Go reprint prompt and reparse.
  5344. cmnb32: mov cmccnt,ah           ; Save the new char count.
  5345.         mov ah,prstr            ; Erase the character.
  5346.         mov dx,offset clrspc
  5347.         int dos
  5348.         mov bx,cmcptr           ; Get the pointer into the buffer.
  5349.         dec bx                  ; Back up in the buffer.
  5350.         dec bx
  5351.         mov cmcptr,bx
  5352.         jmp repars              ; Go reparse everything.
  5353. cminb4: cmp ah,'?'                      ; Is it a question mark.
  5354.         jz cminb6
  5355.         cmp ah,esc                      ; Is it an escape?
  5356.         jz cminb8
  5357.         cmp ah,cr                       ; Is it a carriage return?
  5358.         jz cminb5
  5359.         cmp ah,lf                       ; Is it a line feed?
  5360.         jz cminb5
  5361.         cmp ah,ff                       ; Is it a formfeed?
  5362.         jne cminb7
  5363.         call cmblnk
  5364.     call locate
  5365. cminb5: mov ah,cmccnt           ; Have we parsed any chars yet?
  5366.         cmp ah,1
  5367.     jnz cminb6
  5368.         jmp prserr               ; If not, just start over.
  5369. cminb6: mov ah,0FFH             ; Set the action flag.
  5370.         mov cmaflg,ah
  5371.         jmp cminb9
  5372. cminb7: jmp cminb1        ; Get another char.
  5373.  
  5374. cminb8: mov ah,prstr        ; Don't print the escape char.
  5375.     mov dx,offset escspc
  5376.     int dos
  5377.     jmp cminb6
  5378.  
  5379. cminb9: pop bx
  5380.         pop dx
  5381.         ret
  5382.  
  5383. cmgtch: push cx
  5384.     push bx
  5385.         push dx
  5386. cmgtc1: mov ah,cmaflg
  5387.         cmp ah,0                        ; Is it set.
  5388.         jne cmgt10
  5389.         call cminbf             ; If the action char flag is not set get more.
  5390. cmgt10: mov bx,cmdptr           ; Get a pointer into the buffer.
  5391.         mov ah,[bx]                     ; Get the next char.
  5392.         inc bx
  5393.         mov cmdptr,bx
  5394.         cmp ah,' '                      ; Is it a space?
  5395.         jz cmgtc2
  5396.         cmp ah,tab                      ; Or a tab?
  5397.         jne cmgtc3
  5398. cmgtc2: mov ah,cmsflg           ; Get the space flag.
  5399.         cmp ah,0                        ; Was the last char a space?
  5400.         jne cmgtc1              ; Yes, get another char.
  5401.         mov ah,0FFH             ; Set the space flag.
  5402.         mov cmsflg,ah
  5403.         mov ah,' '
  5404.         pop dx
  5405.         pop bx
  5406.         jmp cmgtc5
  5407. cmgtc3: mov al,0
  5408.         mov cmsflg,al           ; Zero the space flag.
  5409.         pop dx
  5410.         pop bx
  5411.         cmp ah,esc
  5412.         jz cmgtc5
  5413.         cmp ah,'?'                      ; Is the user curious?
  5414.         jz cmgtc4
  5415.         cmp ah,cr
  5416.         jz cmgtc4
  5417.         cmp ah,lf
  5418.         jz cmgtc4
  5419.     cmp ah,ff
  5420.     je cmgtc4
  5421.     pop cx
  5422.     ret            ; Not an action char, just return.
  5423. cmgtc4: dec cmdptr
  5424. cmgtc5: or ah,80H        ; Make the char negative to indicate
  5425.     pop cx
  5426.     ret            ; it is a terminator.
  5427. CMND    ENDP
  5428.  
  5429. ; This routine blanks the screen.
  5430.  
  5431. CMBLNK    PROC    NEAR        ; This is stolen from the IBM example.
  5432. IF ibmpc
  5433.     mov cx,0
  5434.     mov dx,184FH
  5435.     mov bh,7
  5436.     mov ax,600H
  5437.     int bios
  5438. ENDIF
  5439. IF Z100
  5440.     mov ah,prstr        ; Get the function code
  5441.     mov dx,offset clrscr    ; Want to clear the screen
  5442.     int dos            ; Do it
  5443. ENDIF
  5444.     ret
  5445. CMBLNK  ENDP
  5446.  
  5447. ; Cursor control.
  5448.  
  5449. LOCATE  PROC    NEAR
  5450. IF ibmpc
  5451.     mov dx,0        ; Go to top left corner of screen.
  5452.     mov bh,0
  5453.     mov ah,2
  5454.     int bios
  5455. ENDIF
  5456. IF Z100
  5457.     mov ah,prstr        ; Function is print string
  5458.     mov dx,offset homcur    ; Home cursor
  5459.     int dos            ; do it
  5460. ENDIF
  5461.     ret
  5462. LOCATE  ENDP
  5463.  
  5464.  
  5465. MAIN     ENDS            ; End of code section.
  5466.     END    START
  5467.